Unity で テトリス風ゲームを作ってみる(アニメーション#1)
Unity Version 2022.3.4
テトリミノの落下アニメーション#1
前回までで、基本的なテトリスゲームの実装が完了し遊べる形にはなった。今回からは、よりゲームらしくするため、アニメーション処理について考えていく。
通常のゲームでは、ユーザのインタラクションに対するレスポンス表現や、ゲームキャラクター動作の演出などをより効果的に見せるため、随所にアニメーション処理が使われる。
Unity でアニメーション処理を簡単に実現する方法としては、DOTween アセットが有名である。DOTween アセットは無料版と有料版があり、無料版では一部の機能が利用できないが、軽く試してみるには無料版で十分かも。
-
- DOTween の使い方(初歩)
DOTween は、Unity の各Class に対してC#の拡張メソッドを使ってAPIが提供されている。拡張されるClass は、Transform や RectTransform, Material, Camera など多岐にわたる。 例えば、GameObject の位置をアニメーション移動させたいときなどは、Transform に拡張されているDOMove API を使えば実現できる。
例)
using DG.Tweening;
....中略....
var pos = new Vector3 (10, 1, 0); // 移動先のポジション
var duration = 10.0f; // 移動までのアニメーション時間. 単位は秒.
transform.DOMove (pos, duration);
この例の場合、transform の現在位置からpos で指定された位置まで、10秒間かけて移動するというアニメーションが実行される。
pos は、transform の現在位置からの差分ではなく、絶対位置であることに注意。差分で表現したい場合は、
transform.DOMove (pos, duration).SetRelative ();
という指定を行う。こうすることで(現在位置のx 座標 + pos.x, 現在位置のy 座標 + pos.y)へ移動させることができる。
アニメーションを適用する際に、イージングと呼ばれるアニメーション速度の変化量を滑らかにする処理を追加することも可能。
イージングには多くのパターンがあり、こちらが参考になる。
例)
transform.DOMove (pos, duration).SetEase (Ease.InOutCubic);
その他に、複数のアニメーションを順番に実行するためのシーケンス機能や、アニメーションの終了を検知するためのコールバック機能、アニメーションとは関係ない非同期処理を実装するためのバーチャルメソッドなど便利機能が多数存在するが、追々説明を行う(予定)。
-
- テトリミノ自由落下へのアニメーション適用
最初にテトリミノが自由落下する際の移動処理に、DOTween によるアニメーション適応を行ってみる。
今までテトリミノ落下は、単にテトリミノのtransform でlocalPosition.y 座標に1 Unit 下の座標を指定することで実現していた。ここをDOTweenを使った処理に置き換える。
DropAnimation 関数が実態だが、内容はとてもシンプルでTransform Class の拡張メソッドDOLocalMoveY を使って、1 Unit 下の位置に、_fallTime の50% の時間をかけてアニメーション移動させているだけある。絶対時間ではなく、_fallTime の50% と指定しているのは、アニメーション時間が常に次の落下開始までの間に終わるようにするためである。
Tetrimino.cs の抜粋
- private bool FreeFall () {
- var isCollision = false;
- foreach (var block in _blockPrefabs) {
- if (CollisionCheck (block.transform, Vector2.down)) {
- isCollision = true;
- break;
- }
- }
- if (isCollision) return true;
- // 以下をDOTweenで置き換える
- // this.transform.localPosition = new Vector3(
- // this.transform.localPosition.x,
- // this.transform.localPosition.y - 1.0f,
- // this.transform.localPosition.z);
- DropAnimation ();
- return false;
- }
- private void DropAnimation () {
- var pos = this.transform.localPosition;
- this.transform.DOLocalMoveY(pos.y - 1.0f, _fallTime*0.5f).SetEase(Ease.InOutCubic);
- }
実際に適用した結果を動画にしたものが下記になる。
アニメーションありと、なしではかなり印象が変わる。ただ、Easeありとなしは、アニメーション距離が短いせいかあまり差がわからなかった。
次の記事
Unity で テトリス風ゲームを作ってみる(アニメーション#2) - 独習 Unity アプリ開発