#DOTween便利
1週間ほど前にDOTween使い始めました。便利ですねこれ。
ただ、ちょっと探した感じ、オブジェクトを円周上でカーブさせる方法が見つかりませんでした。パスをうまいことやるとそれっぽいことができるようですが、勉強がてら拡張メソッドを書いてみました。
#できたやつ
DOCurveAroundAndRotateの実行の様子。Cylinderを中心にCubeが回転している。
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)