Unityに関連する記事です

 以下の内容で順番に実装を進めていきます。

手順17 ー的球の自動生成処理を実装ー
31.Canvas内に生成位置設定用のゲームオブジェクトを設置する
32.BattleManagerスクリプトを修正する(的球をランダムな位置に自動生成する)



 新しい学習内容は、以下の通りです。

・while文
・Physics2D.Raycastメソッド



31.Canvas内に生成位置設定用のゲームオブジェクトを設置する

設計


 先ほどの手順で的球ゲームオブジェクトをプレファブにしました。
この情報を利用して、ゲームの実行と同時に的球ゲームオブジェクトをBattleManagerクラスから自動的に生成するように処理を追加します。

 生成数はランダムな値とし、ゲーム実行のたびに範囲内で変わるようにします。
その際、的球ゲームオブジェクトの生成される位置もランダムに変わるようにします。

 完全にランダムですと、ゲーム画面外や他の的球や障害物、キャラと同じ位置に生成されてしまうため、条件をつけて生成を行います。

\言する位置は、ゲーム画面内のみとする(UI部分や画面外には生成されないようにする)

∪言する位置に他のゲームオブジェクトが存在する場合には、その位置では生成しないようにする

生成されたゲームオブジェクトは1つのフォルダ役のゲームオブジェクトの子としてまとめておく


 この3点について条件化し、その条件を満たしている場合のみ、的球ゲームオブジェクトを生成するようにします。

 生成範囲の指定を行うため、直接座標を指定することも出来ます。今回は、座標として利用するゲームオブジェクトを配置して、その位置情報を利用する方法で設計します。

 そのためには事前の準備が必要になるため、この手順ではまず、 銑を実装するのに必要なゲームオブジェクトを配置します。


的球ゲームオブジェクトの生成範囲を指定(制限)するゲームオブジェクトを作成する


 2つの空のゲームオブジェクトを作成し、,鉢△両魴錣箸靴討修琉銘崗霾鵑鰺用します。

 ゲーム画面の左下に1つ、右上に1つゲームオブジェクトを作成して設置し、その範囲内を生成範囲と制限することで、
ゲーム画面外やUIに重なって生成されることを防ぎます。


LeftBottomTran ゲームオブジェクトを作成する

 ヒエラルキーのCanvasの上で右クリックをしてメニューを表示し、Create Empty を選択します。
作成された空のゲームオブジェクトの名前を LeftBottomTran に変更します。


ヒエラルキー画像



 この LeftBottomTran ゲームオブジェクトの位置をゲーム画面の左下に配置します。
Scene画像やインスペクター画像を参考に、ゲーム画面内かつ、Bottom_UI よりも上になるように配置してください。


LeftBottomTran ゲームオブジェクト Sceneビュー画像



LeftBottomTran ゲームオブジェクト インスペクター画像



RightTopTran ゲームオブジェクトを作成する

 LeftBottomTran ゲームオブジェクトと同じ手順で作成します。こちらの位置は右上になるように配置します。

 ヒエラルキーのCanvasの上で右クリックをしてメニューを表示し、Create Empty を選択します。
作成された空のゲームオブジェクトの名前を RightTopTran に変更します。


ヒエラルキー画像



 この RightTopTran ゲームオブジェクトの位置をゲーム画面の右上に配置します。
Scene画像やインスペクター画像を参考に、ゲーム画面内かつ、Top_UI よりも下になるように配置してください。


RightTopTran ゲームオブジェクト Sceneビュー画像



RightTopTran ゲームオブジェクト インスペクター画像



 以上で、的球ゲームオブジェクトを生成する際の範囲の制限位置の設定が出来ました。後程、BattleManagerクラスを修正し、アサインして利用します。


的球ゲームオブジェクトを格納するフォルダ役の EnemyPlace ゲームオブジェクトを作成する


 続いて、生成された的球ゲームオブジェクトがヒエラルキー内に乱雑に並ぶことがないよう、の条件を満たすために
生成時にフォルダ役のゲームオブジェクトの子オブジェクトとして生成します。まとめておくことで管理やデバッグが簡便になります。

 ヒエラルキーのCanvasの上で右クリックをしてメニューを表示し、Create Empty を選択します。
作成された空のゲームオブジェクトの名前を EnemyPlace に変更します。
 

ヒエラルキー画像



 EnemyPlace ゲームオブジェクトの位置は RectTransformコンポーネントのPositionがすべて (0, 0, 0)の位置になるようにしてください。
初期値で設定されている場合には問題ありませんが、0 以外になっていた場合には修正してください。


EnemyTran ゲームオブジェクト Sceneビュー画像



EnemyTran ゲームオブジェクト インスペクター画像



 以上に位置情報の設定は完了です。こちらも BattleManagerクラスを修正し、アサインして利用します。


32.BattleManagerスクリプトを修正する(的球をランダムな位置に自動生成する)

設計


 BattleManagerスクリプトを修正して、的球ゲームオブジェクトをランダムな数、ゲーム内のランダムな位置に自動生成するようにします。

 生成位置がゲーム画面内に収まるように範囲制限を行うとともに、Raycast機能を利用して、生成位置にすでに他のゲームオブジェクトが存在していないかを確認し、
何もゲームオブジェクトがない場合だけ生成を行う制御を行います。これにより他のゲームオブジェクトと重なって生成されることを防ぎます。

 このとき、生成する目標回数とこの判定する回数を一緒にしてしまうと、例えば、3回の生成回数に対して生成可能な判定が1回しかできなかった場合、
2回分の生成が行われずにゲームが開始されてしまいます。つまり for 文のような、指定した回数しか繰り返し処理ができないものでは制御が行えません。

 そこで今回は while 文を利用して、実際に生成された回数と生成する目標回数とを一致させることで、判定は何回でも行えるように制御しています。
生成回数で制御するのではなく、実際に生成した回数によって繰り返し処理を制御することで、目標数を満たすまで繰り返し処理を行えるようにしています。


 生成された的球ゲームオブジェクトはListに登録し、後に追加するステージのクリア処理に備えます。
的球ゲームオブジェクトが破壊されるたびに、このListからも情報が削除されていくように制御を行っています。(EnemyBallスクリプトに追記済)


BattleManagerスクリプトを修正する


 自動生成の処理のために、新しい変数を6つ追加します。またメソッドを3つ追加します。

 Initializeメソッドを修正し、手球の生成が終わったあとに、的球ゲームオブジェクトを生成する処理を追加します。
長いですが全文掲載します。ゆっくりと処理の流れを見ながら記述してください。


BattleManager.cs

 <= クリックすると開きます



while文


 反復処理と呼ばれる処理です。条件を満たしている限り、繰り返し処理を行います。

 今回のケースでは条件が「count の値が appearEnemyCountの値よりも低い」ですので、この条件を満たす間はずっと繰り返し処理を行います。
生成に成功するたびに count の値は 1 ずつ加算されます。この値が生成目標である appearEnemyCountの値 になるまでは、生成を続けることになります。
そしてこの条件を満たさなくなったとき = count の値が appearEnemyCountの値よりも同じか大きくなったときには生成が終了した、と判断され、この繰り返し処理が終了し、次の処理へ移ります。

    // 生成する敵の数をランダムで設定
    int appearEnemyCount = Random.Range(2, 5);

    // 生成した数をカウント用
    int count = 0;

    // 生成した数が生成数になるまでループする。目標数になったら生成終了し、ループを抜ける
    while (count < appearEnemyCount) {
   
       // 処理

       // 生成に成功した場合だけ、countを加算する
       count++;

       // 処理
    }

 今回は生成する際に「他のゲームオブジェクトと重複しない」という条件がありますので、回数を指定した反復処理では正常な生成が行えません。

 while 文を利用して「生成に成功した時だけ回数を加算し、その回数が指定値になったら生成を止める」という処理にすることで、
条件を満たさない場合であっても、生成回数に達するまでは何回でも繰り返し処理を行ってくれています。


参考サイト
未確認飛行 C 様
反復処理
https://ufcpp.net/study/csharp/st_loop.html


Physics2D.Raycastメソッド


 ある地点から特定の方向へ向かって Ray という見えない光線を投射して、その間に接触したコライダーを持つゲームオブジェクトの情報を
RaycastHit2D 型で戻してくれるメソッドです。


参考サイト
Unity公式スクリプトリファレンス
Physics2D.Raycast
https://docs.unity3d.com/ja/current/ScriptReferenc...


  // Transform情報を代入
  Transform enemyTran = canvasTran;

  // ^銘屬魏萍牝發房まる範囲でランダムに設定
  enemyTran.position = new Vector2(Random.Range(leftBottomTran.localPosition.x, rightTopTran.localPosition.x), Random.Range(leftBottomTran.localPosition.y, rightTopTran.localPosition.y));

  // ∪瀋蠅靴唇銘屬紡个靴Rayを発射
  RaycastHit2D hit = Physics2D.Raycast(enemyTran.position, Vector3.forward);

  // Rayに当たったオブジェクトを表示。何もないときは null
  Debug.Log(hit.collider);
            
  // い發靴皺燭Rayに当たらない場合(Rayに何か当たった場合にはその位置には生成しないので、ループの最初からやり直す)
  if (hit.collider == null) {

     // 処理

  }

 今回のケースでは、.押璽牴萍牝發離薀鵐瀬爐憤銘屬鮴瀋蠅掘↓△修琉銘屬惴けて Ray を発射します。画面の奥方法(Z方向)に対して発射しているため、
ゲーム画面内の,琉銘屬紡減澆靴討い襯押璽爛ブジェクトのコライダーがあった場合には、そのコライダー情報を取得します。

 コライダー情報が取得できる = 何かゲームオブジェクトが存在している、ということになり、このときはい両魴錣鯔たさないため、
的球ゲームオブジェクトは生成されず、最初からループ処理をやり直します。
つまり、もう一度ランダムな位置を設定して、その位置に Ray を発射する、という流れを繰り返します。

 コライダー情報が取得できない = コライダーを持つゲームが何も存在していない = 手球も、他の的球も、障害物も存在していない位置ということになり、
ここで始めて的球ゲームオブジェクトを生成し、ゲーム内に配置する処理が行われます。同時にListへ登録されて、生成カウントも加算されます。

 生成カウントは生成した際にしか加算されませんので、この手順を繰り返して、他のゲームオブジェクトと重ならない位置に指定数の的球ゲームオブジェクトを生成するまで処理が行われます。


BattleManagerゲームオブジェクトの設定を行う


 BattleManagerクラスを修正しましたので、BattleManagerゲームオブジェクトを選択し、アサイン情報を設定します。
アサイン用の変数名とゲームオブジェクトの名前とを同じになるように設計していますので、同じ名前でアサインを合わせるように出来ます。また間違えてもすぐに気づけます。
 全部で6か所ありますので、順番にアサインしてください。


 enemyBallPrefab 変数には的球(敵)ゲームオブジェクトのプレファブをアサインします。
Prefabフォルダ内にあるEnemyBallゲームオブジェクトをドラッグアンドドロップしてアサインします。

 enemyBallList 変数には何もアサインしません。Size も 0 のままで問題ありません。ここにはゲームの実行時に生成された的球ゲームオブジェクトが代入されます。
ゲームの実行時に確認してください。

 canvasTran 変数にはヒエラルキーにあるCanvasのTransformを登録します。ヒエラルキーのCanvasゲームオブジェクトをドラッグアンドドロップしてアサインします。
この情報は的球ゲームオブジェクトを生成する際に位置・回転情報と親オブジェクトの情報として利用します。


アサイン手順動画
https://gyazo.com/e8f5ac46a80702ee2446cef611906eef


 leftBottomTran 変数にはゲーム画面の左下位置を指定するための Transform 情報をアサインします。先ほど作成した LeftBottomTran ゲームオブジェクトを
ヒエラルキーからドラッグアンドドロップしてアサインしてください。自動的に Transform コンポーネントがアサイン情報として登録されます。

 rightTopTran 変数も、LeftBottomTran 変数と同じ役割です。ゲーム画面の右上位置を指定するためのTransform 情報をアサインします。
先ほど作成した RightTopTran ゲームオブジェクトをヒエラルキーからドラッグアンドドロップしてアサインしてください。自動的に Transform コンポーネントがアサイン情報として登録されます。

 enemyPlace 変数は生成した的球ゲームオブジェクトが格納されるフォルダの役割です。ヒエラルキーの EnemyPlace ゲームオブジェクトをドラッグアンドドロップしてアサインします。


アサイン手順動画
https://gyazo.com/62b8c21800c013ef51b4ac6a0a4a9694


BattleManagerゲームオブジェクト インスペクター画像



EnemyBallクラスのコメントアウトを削除する


 BattleManagerクラスにメソッドが追加されましたので、EnemyBallクラスのDestroyEmenyメソッドのコメントアウトしていた処理を元に戻します。

EnemyBall.cs
    public void DestroyEnemy(Sequence sequence) {
        capsuleCol.enabled = false;

        // 破壊までの時間
        float duration = 0.5f;

        // 内側に小さくする ドロップ内容で消える処理を分岐
        sequence.Join(GetComponent<RectTransform>().DOSizeDelta(new Vector2(0, 100), duration).SetEase(Ease.Linear));

        // 敵の管理
        gameManager.RemoveEnemyList(this);   // <= コメントアウトを解除

        // スケールが0になるタイミングで破棄
        Destroy(gameObject, duration);
    }


ゲームを実行して動作を確認する


 ゲームの実行した際、順番に処理が流れていくかを確認します。まずはBottom_UI内に手球アイコンが生成され、その後、ゲーム画面内に手球ゲームオブジェクトが生成されます。
最後に今回追加した的球ゲームオブジェクトの生成が行われる流れです。ランダムな数とランダムな位置を設定していますので、何回か繰り返してデバッグしてください。
同じ位置に生成されないかも確認します。


実行検証動画
https://gyazo.com/e07ec95f659a4605a5531af8cc7f9d53


 以上でこの手順は終了です。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

3Dトップビューアクション(白猫風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます