椿さんの↓が面白そうだったので作ってみました。
@tsubaki_t1 いや、自分の求めてる動きは多分こっちか pic.twitter.com/3F7uEoCfLd
— 椿 (@tsubaki_t1) 2016年3月15日
↓完成したのがこちら
Step1 GameObject 作成
とりあえず12個 Instantiate
して作っておきます。全部同じ位置に生成してるので重なってます。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
}
Step2 回す
.MotionP()
を使うと XY 座標を動かすモーションを定義出来ます。これにメソッドチェインする形で動き方を指定していきます。まずは .Circular()
を指定しました。Circular は円周を回る動きになります。パラメータは半径と速度です。とりあえず適当な値を指定しておきます。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
g.MotionP().Circular(83f, 0.75f);
}
Step3 円状に並べる
.Angle()
を使用して個々の GameObject の動きを 30 度ずつずらします。これにより、円状に並ぶことになります。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
var angle = 30f * i;
g.MotionP().Circular(83f, 0.75f).Angle(angle);
}
Step4 半径を変化させる
各パラメータは定数だけでなく、時間変化する値を指定することもできます。これを利用して、.Circular()
の半径を時間と共に小さくするようにします。
Velocity.AccelByRatio(v, r)
は毎フレーム v
に r
が乗算された値を生成できます。r > 1.0f
とすれば増幅する値を生成でき、r < 1.0f
とすれば減衰していく値を生成できます。ここでは 218f
から始まって、毎フレーム 0.92f
の割合で小さくなっていくようにしています。
これだと最終的に値が 0f
に収束してしまうので、 .Offset(83f)
で 83f
を足すことで、最小でも半径が 83f
になるようにします。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
var angle = 30f * i;
var radius = Velocity.AccelByRatio(218f, Source.Constant(0.92f)).Offset(83f);
g.MotionP().Circular(radius, 0.75f).Angle(angle);
}
Step5 速度を変化させる
同様にして、速度も減衰させるようにします。だいぶそれっぽくなってきましたね!
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
var angle = 30f * i;
var radius = Velocity.AccelByRatio(218f, Source.Constant(0.92f)).Offset(83f);
var speed = Velocity.AccelByRatio(0.75f, Source.Constant(0.94f));
g.MotionP().Circular(radius, speed).Angle(angle);
}
Step6 味付け
最後に少し味付けしていきます。まず、速度に .Offset(0.01f)
することで、定位置に着いた後も余韻としてちょっとだけ回転を続けるようにします。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
var angle = 30f * i;
var radius = Velocity.AccelByRatio(218f, Source.Constant(0.92f)).Offset(83f);
var speed = Velocity.AccelByRatio(0.75f, Source.Constant(0.94f)).Offset(0.01f);;
g.MotionP().Circular(radius, speed).Angle(angle);
}
次に、Fractional Brownian Motion .Fbm()
で揺らぎを生成して、.AmplifyComponents()
でその揺らぎを X 方向に 0f
倍、Y 方向に 2f
倍することで、縦方向だけに少々うにょうにょさせます。
for (var i = 0; i < 12; ++i) {
g = GameObject.Instantiate(prefab);
g.transform.SetParent(prefab.transform.parent);
g.transform.localPosition = Vector3.zero;
g.transform.localScale = Vector3.one;
var angle = 30f * i;
var radius = Velocity.AccelByRatio(218f, Source.Constant(0.92f)).Offset(83f);
var speed = Velocity.AccelByRatio(0.75f, Source.Constant(0.94f)).Offset(0.01f);;
g.MotionP().Circular(radius, speed).Angle(angle).Fbm(new Vector2(0f, 1f), 3).AmplifyComponents(new Vector2(0f, 0.3f));
}
これにて完成です!組み合わせとパラメータの調整で面白い動きを数行で作れるのが UrMotion の強みですね。
UrMotion のソースとその他のサンプルは以下からどうぞ: