簡単なアニメーションの小ネタをストックしていきます。環境をどうしようかな〜と思ったのですが、絵が出しやすいし、Vectorクラスも充実してるし、結構デファクトスタンダードになってきたしでUnityを選びました。ちょっと座標の指定とか回転とか癖がありますが、そこは、まあ、あれです、なんとかなります(笑)
作るもの
第一回目は簡単にマウストレーサを作ってみます。完成形はこんなかんじになりました。マウスを動かすとそれを追うように、矢印が移動していきます。プログラム
見た目に違わず、アルゴリズムも結構簡単です。座標の指定や回転はUnity方式なので、慣れてないとちょっと読みにくいかもしれませんが、transform.positionで矢印オブジェクトの座標指定、transform.eulerAnglesで矢印オブジェクトの回転を指定していることがわかれば、あとはどの環境でも同じだと思います〜
const float SPEED = 0.1f; void Update () { // マウスの座標をスクリーン座標系に変換 (1) Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Vector3 mousePos = ray.origin; // マウスから矢印へのベクトルを正規化 (2) Vector3 diff = mousePos - transform.position; Vector3 norm = diff.normalized; // 速度ベクトルの計算(3) Vector3 v = norm * SPEED; // 座標と回転の更新 transform.position += v; // マウスの方向を向かせる (4) float deg = Mathf.Atan2( diff.y, diff.x ) * Mathf.Rad2Deg; transform.eulerAngles = new Vector3(0, 0, deg-90); }
アルゴリズムの肝は、現在の矢印オブジェクトとマウスの差分ベクトルを正規化し、それを矢印オブジェクトの速度ベクトルとしているところです。上記プログラムでは、diffが差分ベクトル、normはdiffを長さ1のベクトルに正規化したもの、vが速度ベクトルです。下の図にまとめましたので参考にしてみてください。
解説
(1) Unityは基本3Dを扱っているので、マウスの座標をスクリーン座標系に変換する必要があります。これはお決まりの処理で、mousePosに2Dのスクリーン座標系でのマウス座標が格納されます。
(2)マウスから矢印オブジェクトへの差分ベクトルを計算し、normalizedメソッドをつかって、長さ1の正規化されたベクトル(norm)に変換しています。この計算によりnormは常にマウスの方向を指す長さ1のベクトルになります。
(3) normをそのまま速度として足し込むと、矢印オブジェクトが高速に動きすぎるので、SPEED変数で速度を調整します。
(4) Atan2を使って矢印オブジェクトからみたマウス座標の角度を計算し、矢印をマウス座標に向けて回転しています。これによって常に矢印がマウスの方向を向くようになります。