LoginSignup
5
2

More than 3 years have passed since last update.

DOTweenでカーブさせる

Last updated at Posted at 2020-06-04

DOTween便利

 1週間ほど前にDOTween使い始めました。便利ですねこれ。
 ただ、ちょっと探した感じ、オブジェクトを円周上でカーブさせる方法が見つかりませんでした。パスをうまいことやるとそれっぽいことができるようですが、勉強がてら拡張メソッドを書いてみました。

できたやつ

DOCurveAroundAndRotateの実行の様子。Cylinderを中心にCubeが回転している。
docurve.gif

public static class DoTweenExt
{
    //centerを中心、axisを軸として、degree(度)回転する
    public static TweenerCore<float, float, FloatOptions> DOCurveAround(this Transform transform, Vector3 axis, Vector3 center, float degree, float duration)
    {
        var from = Vector3.negativeInfinity;
        return DOTween.To(() => 0, (x) =>
            {
                if (float.IsNegativeInfinity(from.x)) from = transform.position;
                transform.position = Quaternion.AngleAxis(x, axis) * (from - center) + center;
            },
            degree,
            duration
        );
    }

    //オブジェクトそのものも回転させる
    public static TweenerCore<float, float, FloatOptions> DOCurveAroundAndRotate(this Transform transform, Vector3 axis, Vector3 center, float degree, float duration)
    {
        var from  = Vector3.negativeInfinity;
        var fromRot = Vector3.zero;
        return DOTween.To(() => 0, (x) =>
            {
                if (float.IsNegativeInfinity(from.x))
                {
                    from = transform.position;
                    fromRot = transform.localEulerAngles;
                }
                var q = Quaternion.AngleAxis(x, axis);
                transform.position = q * (from - center) + center;
                transform.localEulerAngles = fromRot + q.eulerAngles;
            },
            degree,
            duration
        );
    }

    //使い方
    //(x,y,z)=(2,0,0)を中心に3秒かけて90度回転させる。
    //transform.DOCurveAround(Vector3.up, new Vector3(2, 0, 0), 90, 3);
}

解説

 みんな大好き、Toメソッドを使います。Toの使い方ですが、

DOTween.To(() => Vector3.zero, (x) => transform.position = x, new Vector3(3, 0, 0), 1);

 (0,0,0)から(3,0,0)に1秒かけて移動します。

DOTween.To(() => 0, (x) => transform.position = new Vector3(x,0,0), 3, 1);

 上と意味は同じですが、変化する値があくまでもプリミティブなfloatになってます。このfloatを角度にして、角度からposition、localEulerAnglesを割り出します。

 それがCurveAroundAndRotateの

var q = Quaternion.AngleAxis(x, axis);
transform.position = q * (from - center) + center;
transform.localEulerAngles = fromRot + q.eulerAngles;

 この部分です。まずはQuaternionを出します。そのQuaternionと回転させたいVector3を掛ければ、(0,0,0)を中心に回転します。fromは開始位置ですが、あくまでもこの関数が走り始める時点での位置です。変数初期化時にtransform.positionを入れてしまうと、Sequenceで動かすときにおかしくなってしまいます。
 角度も同様で、関数が走り出す時点でのeulerAnglesをfromRotにとっておきます。で、fromRotとさっきのQuaternionのeulerAnglesとを足したものを放り込みます。

所感

 Quaternionってすげー

 ※ CurveAroundAndRotateでオブジェクトの向きがうまく変わらないバグがありましたので、修正しました。(2020/6/5)

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2