おれ、Unity2Dでゲーム作るんだ。

Unity2Dをメインに、覚書などを記事にしていきます。

AnimationCurveで値の変化を自由に設定

A地点からB地点に移動などする際に、びよーんとかぐいーんとか、なんとなく気持ちよく動くあれですが、 それをAnimationCurveを使ってやってみようと言う感じです。

f:id:xev:20180522211944p:plain

とりあえず、s地点からe地点に、time時間使って移動する処理。

IEnumerator Move(GameObject obj, Vector3 start, Vector3 end, float time)
{
    obj.transform.position = start;
    while ((obj.transform.position - end).sqrMagnitude > 0.1f)
    {
        Debug.Log((obj.transform.position - end).sqrMagnitude);
        obj.transform.position += (end - start) * Time.deltaTime;
        yield return null;
    }
    obj.transform.position = end;
}

この場合、非常に等速で色気がない移動になります。 そこで、移動量を変化させる仕組みが欲しくなるので、 そこで利用できるのがAnimationCurveです。

public AnimationCurve timelineCurve = AnimationCurve.Linear(0, 0, 1, 1);

こんな感じに宣言してあげれば、インスペクタに良い感じで表示されます。

f:id:xev:20180522211948p:plain

あとは良い感じにカーブをいじります。

f:id:xev:20180522211951p:plain

このカーブを利用したいときは、AnimationCurve.Evaluateを使います。

docs.unity3d.com

AnimationCurve.Evaluateに経過時間を渡してあげれば、いまカーブのどの辺にいるよって返してくれるわけです。

なので、先ほどの等速で動くスクリプトを改造して、

IEnumerator Move(GameObject obj, Vector3 start, Vector3 end, float time)
{
    float during = 0;
    obj.transform.position = start;
    while ((obj.transform.position - end).sqrMagnitude > 0.1f)
    {
        during += Time.deltaTime;
        float t = timelineCurve.Evaluate(during / time);    //経過時間(0~1)を渡すとカーブにおける変化量を返してくれる
        obj.transform.position = startpos + (end - start) * t;    //移動量 * 現在の変化量で、スタート地点からどれくらい移動しているか
        yield return null;
    }
    obj.transform.position = end;
}

こうすれば、びよーんとかぐいーんとか、なんとなく気持ちいい感じに動きます。

もちろん移動だけじゃなく透明度とかサウンドのボリュームフェードなんかにも使えたりと用途はいろいろですね。

ただ、いろいろ独自仕様がいらなければ、DotweenでEase使います。

dotween.demigiant.com

こっちの方が非常に使いやすく高機能です。