おもちゃラボ

Unityで遊びを作ってます

Unityでイージング

Unityで小ネタアニメーション、第5回はイージングです。イージングとは移動速度を何らかの関数にしたがって変化させるもので(あんまりイージングって単語を聞かないですね〜)、アニメーションではよく使われています。例えば、目的地に近づくに連れて速度を落とすとか、最初に猛ダッシュするとか、変化のある移動なので、なんとなく動きが生物っぽくなります

作るもの

ボタンを押すと、左下のボールが右上のボールに向かって動きます。この時、目的地に近づけば近づくほど移動速度が遅くなります。リニアにぴゅーっと動くよりも、ちょっと生物的(人間的?)じゃないですか?


- YouTube


アルゴリズム

イージングのアルゴリズムはとっても簡単です。なんか毎回、簡単簡単と言ってますが、今回こそ簡単です(たぶん)。直線移動の場合には現在位置に同じ大きさの速度ベクトルを足して物体を移動(左図)させますよね。それに対して、イージングの場合には毎フレームごとに異なる大きさの速度ベクトルを足して(右図)いきます。

f:id:nn_hokuson:20141022193756j:plain   f:id:nn_hokuson:20141022193801j:plain

では、どうやってこの速度ベクトルの大きさを決めるのかというと・・・今回のように、目的地に近づくに従って速度を落とす場合は、目的地までの距離に比例するように速度ベクトルの大きさを決めてやればOKです。具体的には、目的地までの距離にある定数(E)をかけることで速度ベクトルとします。

速度=目的地までの距離 * E

つまり、目的地までの距離が遠ければ遠いほど速度も早くなり、近づけば近づくほど速度も遅くなります。更に複雑な動きを実現したい場合には、イージング関数のテーブルを用意してそれにしたがって速度を変化させるという方法がよく使われます。

f:id:nn_hokuson:20141022193551j:plain


プログラム

// 2点間の距離を速度に反映する
Vector3 diff = target.transform.position - transform.position;
Vector3 v = diff * EASING;
transform.position += v;

// 十分近づいたらアニメーション終了
if( diff.magnitude < 0.01f ) 

今回のプログラムはもはや解説するところがないぐらいシンプルです。目的地の座標から現在地の座標を引き、そのベクトルにEASINGの定数(今回は0.05)をかけることで速度ベクトルにしています。その速度ベクトルを、フレームごとに現在の座標に足し込んでいるだけです。

アニメーションの終了条件だけ注意が必要です。この方法の場合、一生目的地にはたどり着けない(限りなくは近づく)ので、終了条件を

if ( transform.position == target.transform.position )

なんて書いた日には、もう目も当てられない状態です。それなりに目的地に近づいた時点でアニメーションを終了させてあげればよいでしょう。

今回使ったC#のスクリプトを置いておきますので
参考にしていただければと思います。

イージングサンプル


参考書籍