はじめに
このチュートリアルは、上記のサイト様が公開されている
ボンバーマン風のゲームを作るチュートリアルを翻訳したものになります
このチュートリアルでは、あらかじめ用意された
モデルやアニメーション、エフェクトのデータを活用して
ボンバーマン風のゲームを作成していきます
目次
開発環境
- Unity 2017.4.0f1
- Windows 10
完成図
Unity プロジェクトの準備
https://koenig-media.raywenderlich.com/uploads/2017/09/Bomberman-HowTo-Starter-Project-1.zip
まず、上記のページにアクセスして、
「Bomberman-HowTo-Starter-Project-1.zip」をダウンロードして展開します
次に、Unity を起動して「Open」を選択し、
展開した「Bomberman HowTo - Starter Project」フォルダを選択します
(「Assets」フォルダと「ProjectSettings」フォルダが格納されているフォルダです)
もし、上記のようなダイアログが表示されたら「Continue」を押します
しばらくすると、Unity プロジェクトが立ち上がります
エディタのレイアウトの変更
次は、作業をしやすくするために Unity エディタのレイアウトを変更します
エディタ右上のボタンを押して、
「2 by 3」を選択します
そして、「Project」と書かれているタブの右側にある三本線のアイコンを押して、
「One Column Layout」を選択します
これでレイアウトの変更が完了しました
Unity プロジェクトの解説
今回は、上記のようにモデルやアニメーション、
エフェクトなどのデータがすでに用意されており、これらを活用していきます
それぞれのフォルダには、下記のようなアセットが用意されています
フォルダ | 内容 |
---|---|
Animation Controllers | プレイヤーモデルのアニメーション |
Materials | ステージに配置されているブロックのマテリアル |
Models | プレイヤー、ステージ、爆弾のモデルとマテリアル |
Music | BGM |
Physics Materials | プレイヤーの物理特性 |
Prefabs | 爆弾と爆発エフェクトのプレハブ |
Scenes | ゲームのシーン |
Scripts | ゲームの挙動を実装するスクリプト |
Sound Effects | 爆弾と爆発エフェクトの SE |
Textures | プレイヤーのテクスチャ |
ゲームの操作方法
「Scenes」フォルダ内の「Game」シーンをダブルクリックして開くと、
プレイヤーとステージが配置されたシーンが立ち上がります
そして、Unity エディタ上部の再生ボタンを押してゲームを再生すると
すでにプレイヤーが操作できるようになっていることが確認できます
1P | 2P | |
---|---|---|
移動 | WASD | 矢印キー |
爆弾の配置 | Space | Enter |
しかし、まだ爆弾の配置はできません
まずは、爆弾を配置するコードを実装していきましょう
コードの実装
爆弾の配置
「Scripts」フォルダ内の「Player.cs」をダブルクリックすると、
お使いの環境に合わせて Visual Studio や MonoDevelop などの、
プログラムを書くためのコードエディタが起動します
/// <summary> /// Drops a bomb beneath the player /// </summary> private void DropBomb () { if (bombPrefab) { //Check if bomb prefab is assigned first } }
176行目あたりに、DropBomb 関数が定義されており、
Space キーや Enter キーを押すと、この関数が呼び出されるようになっています
プレイヤーの足元に爆弾を配置するには、if 文の中に次の行を追加します
// 爆弾のゲームオブジェクトを作成
Instantiate
(
bombPrefab,
myTransform.position,
bombPrefab.transform.rotation
);
そして、スクリプトを保存して Unity に戻り、
Unity を再生して Space キーや Enter キーを押すと、
プレイヤーの足元に爆弾を配置できるようになったことが確認できます
確認ができたら Unity を停止します
今後も、ゲームの動作確認が終わったら
Unity を停止することをわすれないようにしましょう
Unity を停止せずに編集を続けてしまうと、
作業内容が消えてしまう可能性があります
爆弾の配置位置のスナップ
爆弾を配置できるようになりましたが、
配置位置が床のグリッドとズレてしまっているので、修正していきます
Player.cs で先ほど追加したコードを下記のように変更します
// X 座標と Y 座標を四捨五入 var pos = new Vector3 ( Mathf.RoundToInt( myTransform.position.x ), bombPrefab.transform.position.y, Mathf.RoundToInt( myTransform.position.z ) ); // 爆弾のゲームオブジェクトを作成 Instantiate ( bombPrefab, pos, bombPrefab.transform.rotation );
Mathf.RoundToInt を使用すると、指定された値を四捨五入できます
今回のステージは、床のグリッドの間隔が 1 ずつになっているため、
Mathf.RoundToInt を使用することで、爆弾をキレイに配置できるようになります
そして、スクリプトを保存して Unity に戻り、
Unity を再生して Space キーや Enter キーを押すと、
爆弾がキレイに配置できることが確認できます
爆弾の爆発
次は、爆弾の爆発を実装していきます
そのためには、新しいスクリプトが必要になります
「Scripts」フォルダを右クリックして「Create>C# Script」を選択します
作成したスクリプトに「Bomb」と名前を付けます
次に、「Prefabs」フォルダ内の「Bomb」を選択して、
「Add Component」ボタンを押して、
入力欄に「Bomb」と入力して、表示された「Bomb」を選択します
これで、先ほど作成した爆弾のスクリプトを、
爆弾のプレハブに適用することができました
今度は、コードエディタで「Bomb.cs」を開き、
Start 関数に次のコードを追加します
// 3 秒後に Explode 関数を実行 Invoke( "Explode", 3f );
これで、爆弾が作られてから 3 秒後に Explode 関数が呼び出されるようになりました
次は、下記の Explode 関数を Update 関数の下に追加します
// 爆弾が爆発する時の処理 private void Explode() { }
爆弾が爆発したら、爆発エフェクトを表示する必要があるので
Unity エディタから爆発エフェクトを設定できるようにするために、
下記の public 変数を Start 関数の上に追加します
public GameObject explosionPrefab; // 爆発エフェクトのプレハブ
ここで、一旦スクリプトを保存して Unity に戻ります
そして、「Prefabs」フォルダ内の「Bomb」プレハブを選択し、
「Explosion」プレハブを「Explosion Prefab」の欄にドラッグします
これを済ませたら、コードエディタに戻り、Explode 関数に次のコードを追加します
// 爆弾の位置に爆発エフェクトを作成 Instantiate( explosionPrefab, transform.position, Quaternion.identity ); // 爆弾を非表示にする GetComponent<MeshRenderer>().enabled = false; transform.Find( "Collider" ).gameObject.SetActive( false ); // 0.3 秒後に非表示にした爆弾を削除 Destroy( gameObject, 0.3f );
スクリプトを保存して Unity に戻り、
Unity を再生して Space キーや Enter キーを押すと、
爆弾が 3 秒後に爆発することが確認できます
レイヤーの追加
現在、爆弾の爆風は1マス分しか発生しないため、
3マス分広がるようにしていきます
そして、爆風が壁を突き抜けてしまうといけないため、
爆風と壁の当たり判定に使用するレイヤーを作成します
Unity エディタ右上の「Layers」ボタンを押し、「Edit Layers...」を選択します
そして、「Layers」の左の三角マークを押して
表示された「User Layer 8」の欄に「Blocks」と入力します
次は、作成した「Blocks」レイヤーを、ステージに配置されているブロックに適用します
Hierarchy の欄の「Map」オブジェクト内の「Blocks」を選択し、
Inspector の「Layer」のプルダウンメニューを開き、「8. Blocks」を選択します
確認ダイアログが表示されたら、「Yes, change children」を選択します
これで、ステージに配置されているすべてのブロックに
「Blocks」レイヤーを適用することができました
最後に、コードエディタで「Bomb.cs」を開いて、
explosionPrefab 変数の下に下記のコードを追加します
public LayerMask levelMask; // ステージのレイヤー
ここで、一旦スクリプトを保存します
爆風を3マスに広げる
「Bomb.cs」の Explode 関数の下に、次のコードを追加します
// 爆風を広げる private IEnumerator CreateExplosions( Vector3 direction ) { // 2 マス分ループする for ( int i = 1; i < 3; i++ ) { // ブロックとの当たり判定の結果を格納する変数 RaycastHit hit; // 爆風を広げた先に何か存在するか確認 Physics.Raycast ( transform.position + new Vector3( 0, 0.5f, 0 ), direction, out hit, i, levelMask ); // 爆風を広げた先に何も存在しない場合 if ( !hit.collider ) { // 爆風を広げるために、 // 爆発エフェクトのオブジェクトを作成 Instantiate ( explosionPrefab, transform.position + ( i * direction ), explosionPrefab.transform.rotation ); } // 爆風を広げた先にブロックが存在する場合 else { // 爆風はこれ以上広げない break; } // 0.05 秒待ってから、次のマスに爆風を広げる yield return new WaitForSeconds( 0.05f ); } }
少しコードが長いため、一見複雑に見えますが、実際にはブロックと当たり判定を行い、
ブロックが存在しない場合は爆風を広げる、というシンプルな処理になります
詳しくはコード中のコメントを参照してください
これで、爆風を広げる CreateExplosions 関数が準備できたので、
爆発処理を実装している Explosion 関数から呼び出すようにしていきます
Explosion 関数の GetComponent<MeshRenderer>().enabled = false;
の下に
下記のコードを追加します
// 爆風を広げる StartCoroutine( CreateExplosions( Vector3.forward ) ); // 上に広げる StartCoroutine( CreateExplosions( Vector3.right ) ); // 右に広げる StartCoroutine( CreateExplosions( Vector3.back ) ); // 下に広げる StartCoroutine( CreateExplosions( Vector3.left ) ); // 左に広げる
これで、爆風を広げるコードの実装が完了したので、
スクリプトを保存して Unity に戻ります
最後に、「Prefabs」フォルダ内の「Bomb」プレハブを選択し、
Inspector で「Level Mask」を「Blocks」に変更します
これで、Unity を再生して Space キーや Enter キーを押すと、
爆弾が 3 マスに広がって爆発することが確認できます
連鎖
次は、爆風が別の爆弾に触れたら、その爆弾も爆発するようにしていきます
コードエディタで「Bomb.cs」を開き、CreateExplosions 関数の下に
下記のコードを追加します
// 他のオブジェクトがこの爆弾に当たったら呼び出される public void OnTriggerEnter( Collider other ) { }
さらに、すでに爆弾が爆発している場合は連鎖しないようにするために、
levelMask 変数の下に、爆発したかどうかを管理する下記の変数を追加します
private bool exploded = false; // すでに爆発している場合 true
そして、先ほど追加した OnTriggerEnter 関数の中に下記のコードを追加します
// まだ爆発していない、 // かつ、この爆弾にぶつかったオブジェクトが爆発エフェクトの場合 if ( !exploded && other.CompareTag( "Explosion" ) ) { // 2 重に爆発処理が実行されないように // すでに爆発処理が実行されている場合は止める CancelInvoke( "Explode" ); // 爆発する Explode(); }
最後に、Explosion 関数の GetComponent<MeshRenderer>().enabled = false;
の下に
爆発したかどうかを管理する exploded を更新する下記のコードを追加します
// 爆発した exploded = true;
これで、Unity を再生して Space キーや Enter キーを押すと、
爆弾が連鎖して爆発するようになったことが確認できます
プレイヤーの死
ここまでで、爆弾が爆発する処理の実装が完了したので、
あとは、ゲームの終了処理を作成していきます
まず、コードエディタで「Player.cs」を開き、
canMove 変数の下に下記のコードを追加します
public bool dead = false; // 死亡した場合 true
この変数は、プレイヤーが爆発で死亡したかどうかを管理する変数です
続いて、下記のコードも追加します
public GlobalStateManager globalManager; // ゲームの状態を管理するスクリプト
GlobalStateManager は、どのプレイヤーが勝利したのかを判断するスクリプトです
プレイヤーが死亡したら、globalManager 変数に通知します
「Player.cs」の末尾には、OnTriggerEnter 関数がすでに定義されており、
プレイヤーが爆風に触れたかどうかを確認する if 文が記述されています
OnTriggerEnter 関数の Debug.Log の呼び出しの下に、下記のコードを追加します
// 死亡した dead = true; // ゲームの状態を管理するスクリプトに // 死亡したプレイヤーの番号を通知 globalManager.PlayerDied( playerNumber ); // プレイヤーを削除 Destroy( gameObject );
ここで、一旦スクリプトを保存して Unity に戻り、
Hierarchy の欄で「Player1」と「Player2」を選択します
(Ctrl キーを押しながらクリックすると、同時に選択できます)
「Global State Manager」オブジェクトを、
「Global Manager」の欄にドラッグして設定します
これで、Unity を再生すると、
爆風がプレイヤーに触れた時に、プレイヤーが死亡することが確認できます
勝敗判定
最後に、どちらのプレイヤーが勝利したのか判定する処理を実装していきます
コードエディタで「GlobalStateManager.cs」を開き、
PlayerDied 関数の上に、下記のコードを追加します
private int deadPlayers = 0; // 死亡したプレイヤーの数 private int deadPlayerNumber = -1; // 死亡したプレイヤーの番号
次に、PlayerDied 関数の中に下記のコードを追加します
// 死亡したプレイヤーの数を増やす deadPlayers++; // 1 人のプレイヤーが死亡したら if ( deadPlayers == 1 ) { // 死亡したプレイヤーの番号を保持し、 deadPlayerNumber = playerNumber; // 0.3f 秒後に CheckPlayersDeath 関数を呼び出す Invoke( "CheckPlayersDeath", 0.3f ); }
そして、最後に、PlayerDied 関数の下に下記のコードを追加します
void CheckPlayersDeath() { // 死亡したプレイヤーが 1 人だけの場合 if ( deadPlayers == 1 ) { // プレイヤー 1 が死亡した場合 if ( deadPlayerNumber == 1 ) { // プレイヤー 2 が勝利した Debug.Log( "プレイヤー 2 の勝利!" ); } // プレイヤー 2 が死亡した場合 else { // プレイヤー 1 が勝利した Debug.Log( "プレイヤー 1 の勝利!" ); } } // すべてのプレイヤーが死亡した場合 else { // 引き分け Debug.Log( "引き分け" ); } }
これで、スクリプトを保存して Unity に戻り、
Unity を再生して、爆風がプレイヤーに触れると、
Console ウィンドウに対戦結果が出力されることが確認できます
(Console ウィンドウは Ctrl + Shift + C を押すと表示されます)
以上で、ボンバーマン風のゲームを作るチュートリアルが終わりとなります
さいごに
https://koenig-media.raywenderlich.com/uploads/2017/09/Bomberman-How-To-Final-Project.zip
チュートリアルの完成プロジェクトは、上記のページからダウンロードできます
このチュートリアルでは、主に爆弾の配置や爆発、
勝敗判定の実装方法を紹介してきました
興味があれば、下記のようなロジックも実装してみて頂ければと思います
- 爆弾を押せるようにする
- 配置できる爆弾の数を制限する
- リトライ機能を実装する
- 爆風で破壊できるブロックを配置する
- パワーアップアイテムを作成する
- 勝敗判定の結果を UI で表示する
- より多くのプレイヤーを操作できるようにする