Unityではじめてのテトリス風落ちゲー制作記 ~その2 壁ブロック表示編~

Unity

Unityでテトリス風落ちゲーを作ってみたいけど、何から手を付けていいか分からない。私もそんな一人です。ここでは、自分の勉強も含めて、簡単なテトリス風落ちゲーを制作していく過程を掲載していきます。

この連載を最後まで読めば、このようなテトリス風落ちゲーが1人で作れるようになります。

別ウィンドウで開く場合はこちら

今回はブロック表示編として、壁ブロックをゲーム画面上に表示するところまで解説していきます。

まだゲーム設計編を読んでない方は、こちらを先に読むことをお勧めします。

この記事はこんな人におすすめ!

  • 用意されたアセットを極力使わず、自分の力でゲームを作りたい
  • プログラミング初心者で1つ1つ丁寧に解説した記事が読みたい
  • Unity初心者がスキルを上げながらゲームを制作していく過程を見たい

尚、ここでの制作過程はすべて自己流です。もっと簡単に作る方法もあると思いますので、ご了承下さい。

ブロック Prefabの作成

ブロックオブジェクトはゲーム制作で何回も使用します。毎回ブロックオブジェクトを作っていては面倒ですよね。それを解消するのがPrefabです。

Prefabとは、作成したオブジェクトを再利用する仕組みのことです。Inspector上の設定が引き継がれ、簡単に同じオブジェクトが複製出来ます。今回のように、複数の壁ブロック、落下ブロック、配置ブロックを作成するには無くてはならない機能です。

ブロック画像データの準備

まず、ブロック画像を準備しないといけません。自分でデザイン出来る人は、ブロック画像をデザインしましょう。私は、フリー素材を使わせてもらいます。illust ACよりrare-canさんが作成したブロック画像を使用させて頂きました。

ダウンロードした画像をAssetsフォルダにドラッグして追加します。

画像データは複数のブロックが含まれています。1つのブロック画像を抽出するため、追加した画像をクリックし、InspectorタブからTexture Type、Sprite Modeを設定します。

Texture Typeは、Sprite (2D and UI)、Sprite ModeはMultipleを設定し、Sprite Editorボタンをクリックして下さい。

Sprite Editorが開いたら、Sliceボタンをクリックしましょう。

画像は10×10のセルになっています。TypeをGrid By Cell Countに変更し、Columnを10、Rowを10に設定することで、1セルごとに分割出来ます。

Applyボタンを押すと、画像を分割出来ました!

ブロック画像データからSpriteの作成

分割した画像からSprite(2Dグラフィックオブジェクト)を作成します。分割した画像をHierarchyタブにドラッグしてください。Spriteが出来上がります。

ブロックのPrefab化

ブロックを再利用出来るようにPrefabにします。

まず、壁ブロックのPrefab化です。壁ブロックは紫色にしました。オブジェクト名を「Wall Block」に変更し、Prefabsフォルダにドラッグします。これでPrefab化完了です。簡単ですね。Wall BlockをPrefab化しておけば、いつでもWall Blockを再利用出来ますので、一旦HierarchyタブからWall Blockを削除します。

同様に落下ブロック、配置ブロックもPrefab化します。落下ブロックは黄緑色、配置ブロックは青色にしました。

壁ブロックの画面配置

スクリプトで壁ブロックを配置

壁ブロックをゲーム画面に配置していきましょう!

壁ブロックは10✕18マスの配置領域の左右&下に配置します。一つずつオブジェクトを並べても良いですが、スクリプトを使います。

まず、Hierarchyタブの+ボタンをクリックし、Create Emptyを選択して下さい。

空のオブジェクトが作成されますので、名前をGame Controllerに変更します。

InspectorタブのAdd Componentボタンをクリックし、New Scriptを選びます。

名前GameControllerとしました。Create and Addボタンを押して下さい。

AssetsフォルダにGameController.csファイルが作られるとともに、GameControllerオブジェクトのInspectorタブにスクリプトのコンポーネントが追加されます。

続いて壁ブロックを配置するスクリプトを作成していきましょう!スクリプトはC#で記述していきます。GameController.csを開いて下さい。ファイルを開くにはAssetsフォルダから開いても良いですし、Inspectorタブから開くこともできます。

私はエディタをVisual Studio Codeに設定しています。

スクリプトを開くと、初期段階でStartメソッドとUpdateメソッドが生成されていますね。Startメソッドは最初のフレームがアップデートされる前に呼び出されます。Updateメソッドは1フレームごとに呼び出されます。

壁ブロックはゲーム中、常にゲーム画面に表示されますので、Startメソッドにプログラムを記述していきます。

ゲーム設計編で落下ブロックを配置する領域は縦18×横10マスにするとしましたね。そこで、各マスのブロック配置状態を下記のように定義し、

  • 0: 空
  • 1: 壁ブロック
  • 2: 落下ブロック
  • 3: 配置ブロック

左右の壁マス、下の壁マス、ダミーマスを加えた縦21×横14の配列でブロック配置状態を管理します。ダミーマスを加える理由は、落下ブロック群を4×4マスで定義し、左上のマスを基準位置とする予定で、右壁/下壁に近づいたときのプログラム破綻を防止するためです。

壁ブロック位置状態は下図となります。

壁ブロックをゲーム画面に表示するプログラムは下記になります。記事内でプログラムを記述していきますが、必要部分のみ抜粋していきます。

public class GameController : MonoBehaviour
{
    public float OX, OY; // 原点座標
    public GameObject wallBlockPfb; // 壁ブロックPrefab
    private int[,] blockStat = new int[21,14]; // 各マスのブロック状態
    
    private int[,] wallBlockPos = new int[21,14]{
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,0,0,0,0,0,0,0,0,0,0,1,0,0},
        {1,1,1,1,1,1,1,1,1,1,1,1,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };

    void Start()
    {
        blockStat = wallBlockPos;
        // 壁ブロックの配置
        for(int i=0; i<12; i++){
            for(int j=0; j<19; j++){
                if(blockStat[j,i] == 1){
                    Instantiate(wallBlockPfb, new Vector3(i + OX, -j + OY, 0), Quaternion.identity);  
                }
            }
        }
    }

}

Instantiateメソッドは、第1引数で指定したオブジェクトを第2引数で指定した位置に生成する関数です。wallBlockPfb、OX、OYのアクセス修飾子はpublicとしていますので、UnityのInpectorタブから指定できます。

VS codeからUnityに移動しましょう。Game ControllerコンポーネントにwallBlockPfb、OX、OYが追加されています。とりあえずOXとOYは0にしておきます。wallBlockPfbは何も指定されていなくNoneとなっていますので、作成しておいたWall Block PrefabをwallBlockObj欄にドラッグします。

これで壁ブロックがゲーム画面に表示されるはずです。Playボタンを押してゲームを開始してみましょう!

ありゃ。ブロックが重なっているのとカメラ表示範囲が適切でないですね。

壁ブロックの大きさとカメラ表示範囲の調整

まず、ブロックの大きさを調整します。Wall Block PrefabのTransform / ScaleをX: 1→0.4、Y: 1→0.4に変更して下さい。

次にカメラ表示範囲調整です。HierarchyタブからMain Cameraオブジェクトを選択し、Inspectorタブ / CameraコンポーネントのSizeを18に変更します。

また、 Game Controllerオブジェクトを選択し、GameControllerコンポーネントのOXを-5、OYを8に変更します。

もう一度Playボタンを押してゲームを開始してみましょう。

壁ブロックの重なりも解消されるとともに、ゲーム画面に壁ブロックが入りきりましたね。ゲーム画面レイアウトは、ゲーム制作が進むにつれて変更したくなると思います。そんなときは壁ブロックの原点、カメラサイズを変更すれば自由にレイアウト可能です。

まとめ

今回は、壁ブロックをゲーム画面に表示するまでを解説しました。

復習しますと

  • ブロック画像データの準備
  • ブロック画像データからSpriteの作成
  • ブロックのPrefab化
  • スクリプトで壁ブロックを配置
  • 壁ブロックの大きさとカメラ表示範囲の調整

です。

ゲーム画面の土台が出来上がりましたね。

次回は落下ブロックをゲーム画面に表示するまでの制作過程を解説する予定です。

最後までお読み頂きありがとうございました。