魔法陣を回転させよう（アイテムの追従とクォータニオン）

# ご挨拶
おはこんばんにちは。
何故か自分だけの武器って欲しくなったりしますよね。魔法の杖とか魔法の杖とか。
しかし実際に作ろうとすると杖とそれに追従する魔法陣、おまけに回転させる必要があります。

今回の内容は昔に色々と試行錯誤したときのお話なので、少々くどくなっています。
くどい代わりに段階を踏んでいるので、理解しやすければ・・いいなぁ。
最終的な結果を知りたい方は最後まで飛ばしてください。
（オブジェクトに追従するアイテムはこうすればという例としていただければと思います。）

## ○獲物を用意する
画像のようにサクッとUnityで杖と魔法陣を用意しました。
わかりやすく魔法陣は球にXYZを示す棒を差し込んであります。
（荒ぶる事があるので棒のコライダーは削除しておくこと。）
![1 unity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/fb5d0a6d-a2bb-58b2-109e-33514dc66f1e.png)


## ○手始めに魔法陣を回転させよう
まずは基本の練習として魔法陣となるオブジェクトを回転させてみましょう。

```Lua
local magic_rod=vci.assets.GetTransform("magic_rod") --①
local magic_Circle=vci.assets.GetTransform("magic_Circle") --①
	
local count=0 --②
	
function update()
	count=count+1 --③

    magic_rotation=Quaternion.Euler(0,count,0) --④⑤
	magic_Circle.SetRotation(magic_rotation) --⑥
end

 ```
 :::note info
①魔法の杖と魔法陣のオブジェクトを定義します。
②関数「count」を0で定義します。
③毎フレーム毎に関数「count」に+1します。
④関数「Quaternion.Euler(X度,Y度,Z度)」で角度をクォータニオンに変換します。
　今回はY軸の角度だけを変化させるため、Y軸に「count」を使用しています。
⑤変数「magic_rotation」にクォータニオンに変換させた値を入れます。
⑥魔法陣を回転させるため、変数「magic_rotation」の値を入れます。

補足
　Unity等の3D空間での回転軸はXYZの3軸（オイラー角）ではなく
　クォータニオンと呼ばれる4つの値（四元数）を使用します。
  （何故クォータニオンかというと、ジンバルロック問題や計算負荷低減など。
  　詳しくはぐぐってね！）
:::

![2_y軸回転.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/43135cc6-2334-2b32-7467-82eb886c9d8c.gif)

動画のように魔法陣がY軸にそって回転してくれました。
しかしこれは回転しているだけで杖に追従してくれません。

## ○魔法陣を杖に追従させよう
杖からY軸へ1.5m高い位置に魔法陣を追従させましょう。
```Lua
local magic_rod=vci.assets.GetTransform("magic_rod")
local magic_Circle=vci.assets.GetTransform("magic_Circle")

function update()
    magic_rod_position = magic_rod.GetPosition() --①
    magic_Circle_position = magic_rod_position+Vector3.__new(0,1.5,0) --②

    magic_Circle.SetPosition(magic_Circle_position) --③
end
```
:::note info
①関数「magic_rod_position」に「GetPosition」した杖の座標を入れます。
②座標系を作るには、関数「Vector3.__new(X座標,Y座標,Z座標)」で作成します。
　今回の例では変数「magic_Circle_position」に杖の座標（magic_rod_position）に
　Y軸+1.5した値を入れます。
③魔法陣の位置を指定するため変数「magic_Circle_position」の値を入れます。
:::

![3_y座標のみ追従.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/368d9b1e-c86e-993b-9909-328c8a2f5c5e.gif)

これではいけませんね。
動画のように、あくまでも杖の中心から1.5ｍ上に魔法陣を配置するだけのため、
まったく杖先に魔法陣が追従してくれません。

## ○魔法陣を杖先に追従させよう
杖先に魔法陣が無いのはかっこ悪いので対応しましょう。
```Lua
local magic_rod=vci.assets.GetTransform("magic_rod")
local magic_Circle=vci.assets.GetTransform("magic_Circle")

function update()
    magic_rod_position = magic_rod.GetPosition()
    magic_rod_rotation = magic_rod.GetRotation() --①

    magic_Circle_position = magic_rod_position+magic_rod_rotation*Vector3.__new(0,1.5,0) --②

    magic_Circle.SetPosition(magic_Circle_position)
end
 ```
 :::note info
①変数「magic_rod_rotation」に「GetRotation」で取得した杖の角度を入れます。
　つまり、杖の座標（position）+杖の角度（rotation）*魔法陣の位置
②「Vector3.__new(0,1.5,0)」に変数「magic_rod_rotation」をかけ算した物を、
　杖の座標に足します。
:::
 ![4_杖先に追従するだけ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/50257a2b-e222-18b1-0600-72172635235e.gif)

角度（クォータニオン）に位置（X、Y、Z）をかけ算することにより、
三角関数的な計算をしなくても簡単に杖に魔法陣が追従するようになりした。
しかし魔法陣は特定の角度の維持したまま。杖の軸に沿って角度が追従していません。

## ○こんどは魔法陣を杖先に位置も角度も追従させよう
魔法陣の方向が杖先と角度が違うのはこれもかっこ悪い。対応しましょう。
```Lua
local magic_rod=vci.assets.GetTransform("magic_rod")
local magic_Circle=vci.assets.GetTransform("magic_Circle")

function update()
    magic_rod_position = magic_rod.GetPosition()
    magic_rod_rotation = magic_rod.GetRotation()

    magic_Circle_position = magic_rod_position+magic_rod_rotation*Vector3.__new(0,1.5,0)
    magic_Circle_rotation = magic_rod_rotation --①

    magic_Circle.SetPosition(magic_Circle_position)
    magic_Circle.SetRotation(magic_Circle_rotation) --②
end
 ```
 :::note info
①変数「magic_Circle_rotation」に取得した杖の角度を入れる
②魔法陣の角度へ変数「magic_Circle_rotation」を入れる。
:::
 
 ![5_軸にも追従.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/5e58bbc1-329e-ebb0-e4e9-bce022efb521.gif)
 
ちょぴっとコードを書き足すだけで杖の軸に沿って魔法陣も方向が揃いました。

## ○魔法陣を杖先で回転させよう！
いよいよ今までの総仕上げ。魔法陣を杖先で回転させていきましょう。
```Lua
local magic_rod=vci.assets.GetTransform("magic_rod")
local magic_Circle=vci.assets.GetTransform("magic_Circle")
local count=0

function update()
    count=count+1

    magic_rod_position = magic_rod.GetPosition()
    magic_rod_rotation = magic_rod.GetRotation()

    magic_Circle_position = magic_rod_position+magic_rod_rotation*Vector3.__new(0,1.5,0)
    magic_Circle_rotation = magic_rod_rotation*Quaternion.Euler(0,count,0) --①

    magic_Circle.SetPosition(magic_Circle_position)
    magic_Circle.SetRotation(magic_Circle_rotation)
end
 ```
 :::note info
①杖の角度とクォータニオン化した回転座標をかけ算します。
:::
　このようにクォータニオンをかけ算しているだけで複雑なことはしていません。
　（クォータニオン自体わかりにくいのはおいておいて。）

![6_回転しながら軸に追従.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/a82b3f5f-6b19-b100-734d-7cee72de577e.gif)
杖先に魔法陣が追従し、さらに杖の軸に沿って魔法陣が回転させることが出来ました。

## ○最後に
　後は良い感じの杖と魔法陣、エフェクト等を用意し応用することで、
 　動画のような物を作ることが出来ます。

  ![7_魔方陣.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2353185/4026832e-d7e0-55eb-e38e-586755acd606.gif)

　このほかにも親オブジェクトに追従するボタンのような物を作成するにも
 　応用出来るかと思います。
  
　他にも技があるならむしろ教えて！

　みなさんも魔法をぶっぱしたくなったら作ってみましょう！