Unity で テトリス風ゲームを作ってみる(実装編)#6
前回の続き
前回フィールドの作成、ライン削除・落下処理の説明を行った。今回はタイトル画面からスタートボタンでゲームを開始し、テトリミノをフィールドに配置して落下させるまでを説明する。
タイトル画面
タイトル画面UI は以前検討したとおりシンプルにタイトルのテキストと、スタートボタンのみを配置する。Canvas オブジェクト上に、Panel オブジェクト(GameTitle)を配置し、その上にText オブジェクトとButton オブジェクトを配置すればOK。
Button コンポーネントのコールバック設定
ボタンが押されたときのコールバックを受け取るには、Button コンポーネントの"On Click ()"設定に、コールバック関数(引数なしのvoid関数)を設定すればよい。今回の実装では、GameControl クラスにOnStartClick メソッドを作成し、それをコールバック関数に設定している。
スタートボタンのコールバック関数(GameControl.OnStartClick)では、GameObject.SetActive メソッドを使って、Game Title UI とGame Over UI を非表示にして、Game Play UI を表示に変更する。その後、各オブジェクトの初期化関数を呼び出す。
GameControl.cs の抜粋(スタートボタンコールバック)
- // Button Event Callback
- public void OnStartClick () {
- _gameTitlePanel.SetActive(false);
- _gamePlayPanel.SetActive(true);
- _gameOverPanel.SetActive(false);
- GameStart();
- }
- private void GameStart () {
- _field?.Init(this);
- _nextArea?.Init();
- CreateLevelScore();
- PrepareNextTetrimino();
- _state = State.Droping;
- }
GameStart メソッドから呼ばれるPrepareNextTetrimino メソッドでは、NextArea にテトリミノ生成を指示し、生成したテトリミノをField オブジェクトにPushする。
Pushが失敗した場合は、NextArea からField 移動直後に他ブロックに衝突したという意味になるため、GameOverと判定してステータスをState.GameOver し、WaitGameOver メソッド経由で、GameOver UI を表示する。
GameControl.cs の抜粋(テトリミノの準備)
- private void PrepareNextTetrimino() {
- _nextArea.CreateNextTetrimino();
- PushTetrimino2Field();
- _nextArea.CreateNextTetrimino();
- _readyTetrimino = false;
- }
- private void PushTetrimino2Field () {
- var tetrimino = _nextArea.GetNextTetrimino();
- var success = _field.PushTetrimino(tetrimino);
- if (!success) {
- _state = State.GameOver;
- WaitGameOver();
- }
Field オブジェクトは、Push されたテトリミノの親オブジェクトを自分自身に設定し、位置をテトリミノ落下開始位置であるフィールド中央、上部に移動する。
最後にTetrimino クラスのStartDrop メソッドを呼び出すことで、テトリミノオブジェクトの落下を開始させる。落下時点で、既に他ブロックにより落下が失敗した場合はfalse の戻り値を返す。
Field.cs の抜粋(フィールドへのテトリミノ投下)
- public bool PushTetrimino (Tetrimino tetrimino) {
- _tetrimino = tetrimino;
- _tetrimino.SetListner (this);
- _tetrimino.transform.SetParent(this.transform);
- _tetrimino.transform.localPosition = new Vector3(
- ScreenConfig.START_POS_X + ScreenConfig.FIELD_SIDE_WIDTH,
- ScreenConfig.START_POS_Y + ScreenConfig.FIELD_BOTTOM_WIDTH,
- 0);
- if (!_tetrimino.StartDrop()) {
- // GameOver
- return false;
- }
- return true;
- }
DOTweenを使った非同期処理
Unity で非同期処理を扱う方法はいろいろあるが、後々アニメーションを実装することを考えるとDOTween というアセットライブラリを使うのが簡単だ。
DOTween は、Transform などUnity のさまざまなコンポーネントのパラメータを非同期的に変化させることで、簡単にアニメーションを実装することができるライブラリである。DOTween は利用者が多く、日本語のドキュメントや解説記事が豊富で使用するのに敷居が低いというメリットもある。DOTween でググるとたくさんの記事がヒットする。
GameControl クラスのWaitGameOver 関数は、Game Over UI に切り替えるまで少し時間を開けるための非同期処理としてDOTween を使っている。これは、テトリミノをNextArea からField に移動した直後すぐにGameOver 画面を表示すると、ユーザーがなぜGameOver になったのか認知することが難しいためである。
DOTween にはアニメーション処理以外にも下記のようなディレイメソッドも用意されており、簡単に非同期の遅延処理を実現することができる。
GameControl.cs の抜粋(画面切り替えの遅延処理)
- private void WaitGameOver () {
- DOVirtual.DelayedCall(2, () => {
- _gameOverPanel.SetActive(true);
- });
- }
DOTween で利用可能なAPI の説明は、ここ(DOTween - Documentation)を参照するのが詳しいが、上記の DOVirtual.DelayedCall は、指定した秒数(上記では2 秒)たったら、コールバック関数(上記ではラムダ関数を直接指定)を呼び出してくれるというAPI である。たったこれだけの記述で非同期関数を実現することができて非常に便利である。 DOTween の本領はアニメーション処理であるが、そこについては別途説明を追加する予定。
次の記事