独習 Unity アプリ開発

独習でスマフォ向けアプリ開発を勉強中

Unity で テトリス風ゲームを作ってみる(実装編)#4

 Unity Version 2022.3.4

 

前回の続き


前回、入力イベントとテトリミノの移動を説明した。今回はテトリミノの回転について実装方法の説明をする。

 

テトリミノの回転


左右回転キーのAction は、下記のOnTurnLeftEvent とOnTurnRightEvent コールバック関数に割り当てる。左右移動と同様に、InputActionPhase.Started のイベントだけに反応するようにフィルターをかける。左右どちらの回転も結局は回転方向が異なるだけで、処理自体は同一のため、共通の回転関数Rotate を作る。

 

Tetrimino.cs の抜粋(左右回転キーイベントコールバック)

  1.   public void OnTurnLeftEvent (InputAction.CallbackContext context) {
  2.     if (IsOperatable() && context.phase == InputActionPhase.Started) {
  3.       Rotate(90);
  4.     }
  5.   }
  6.  
  7.   public void OnTurnRightEvent (InputAction.CallbackContext context) {
  8.     if (IsOperatable() && context.phase == InputActionPhase.Started) {
  9.       Rotate(-90);
  10.     }
  11.   }
  12.  

 

Rotate 関数は回転角を引数で受け取り、現在の回転角と足して、回転角ごとのenum 値に変換する。enum 値に変換するのはブロック座標配列のIndex に変換する必要があるため。Tetriminio.Type と Tetrimino.Rotation から回転後の4 つのブロックの座標を配列から取得し(BlockPosition 関数)、それぞれのポジションに対して他のブロックがないかを確認する(CollisioinChek 関数)。他のブロックがなければ、回転角をメンバ_rotation に保存して、回転後の位置に各ブロックを移動する(LocateBlocks 関数)

 

Tetrimino.cs の抜粋(左右回転)

  1.   public void Rotate (int degree) {
  2.     var rotation = RotateAngle(_rotation, degree);
  3.     var positions = BlocksPosition(_type, rotation);
  4.     foreach (var pos in positions)
  5.       if (CollisionCheck(this.transform.position + new Vector3(pos.x, pos.y, 0))) return;
  6.     _rotation = rotation;
  7.     LocateBlocks();
  8.   }
  9.  
  10.   private Rotation RotateAngle (Rotation rotation, int degree) {
  11.     var deg = degree % 360;
  12.     var rot = ((int)rotation * 90 + deg);
  13.     if (rot < 0) rot = 360 + rot;
  14.     rot = rot / 90;
  15.  
  16.     switch (rot) {
  17.       case 0:
  18.         return Rotation.R0;
  19.       case 1:
  20.         return Rotation.R90;
  21.       case 2:
  22.         return Rotation.R180;
  23.       case 3:
  24.         return Rotation.R270;
  25.       default:
  26.         return Rotation.R0;
  27.     }
  28.   }
  29.  
  30.   private bool CollisionCheck (Vector2 position) {
  31.     var hitResult = new List<RaycastHit2D>();
  32.     var start = position;
  33.     var length = 0.1f;
  34.     var direct = Vector2.down;
  35.     var hitCount = Physics2D.Raycast(
  36.       start, // レイの原点
  37.       direct, // レイの方向
  38.       _contactFilter, // チェックする対象を設定するフィルター
  39.       hitResult, // ヒットしたオブジェクトの情報
  40.       length // レイの長さ
  41.       );
  42.  
  43.     //Debug.DrawRay(start, direct * length, Color.blue, 1f); // Debug用
  44.     
  45.     return (hitCount > 0)? true : false;
  46.   }
  47.  
  48.   public List<GameObject> GetBlocks() {
  49.     return _blockPrefabs;
  50.   }
  51.  

 

以上でテトリミノの回転は終了。考え方は左右移動とほぼ同じで、移動するか回転するかの違いだけ。

 

次の記事


from20150817.hatenablog.com

 

 


目次に戻る