いのいち勉強日記

Sakana AIでResearch Engineerをしています。京大薬学研究科でPhDをとりました。Kaggle Grandmasterです。

【Unity】シューティングゲームを作ってみよう!《Day 2》プレハブ、一定間隔オブジェクト生成、親オブジェクトの指定

2日目は弾と敵球をプレハブ化して

それぞれ目的のタイミングで出てくるようにします!

弾と敵球ってややこしいので弾:Bullet、敵球:Enemyとします。

 

 

ゲーム作り2日目

 

BulletとEnemyのPrefab化

 

BulletとEnemyをプレハブ化しました。

そうすることで任意のタイミングで出せるようにしました。

しかし、あとでインスタンス化した時に気付いたのですが、

ここでちょっとしたトラブルがありました。

BulletとEnemyはフォルダからドラッグで持っていって配置しました。

そしてその時色々と大きさをいじったのですが、

xとyのScaleが60くらいになっていました。

そしてそれをプレハブ化してインスタンス化して実行してみたのですが、

なんと巨大なEnemyとBulletがでてきました!

f:id:sys-bio:20180326215437p:plain

どうやらプレハブ化した時に

オリジナルオブジェクトのScaleが1にリセットされ

プレハブをインスタンス化した時にその60倍として出てきたようです。

ですので、プレハブのScaleを1付近に直したら思ってたサイズになりました!

プレハブやGameObjectの理解がまだまだで結局よくわからないままですが…

とりあえず予定の大きさにできたので、よしとします!

しかし、実際はどうやるのが正しいのでしょうか…

 

Enemyを一定間隔でインスタンス化

 

元に戻りましてプレハブ化したあと、

次にEnemyを上からどんどん出てくるようにしました。

自動的に出てくるようにするため、これはGameManagerにコードを書きました。

「public GameObject 」でEnemyPrefabを定義して関連づけて、

Update関数の中でインスタンス化しました。

インスタンスのx方向の場所をランダムに出てくるようにしました!

ここで、一定間隔でEnemyを発生させるために

「Time.deltaTime」を使いました!

これは前回フレームからのミリ秒を取得してくれるようです!

実際の概要はコードはこんな感じです!

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

  void Update () {
        timeRedEnemy += Time.deltaTime;
        if (timeRedEnemy > intervalRedEnemy) {
            redEnemy = Instantiate (redEnemyPrefab) as GameObject;
            redEnemy.transform.localPosition =\

         new Vector3 (Random.Range (-300.0f, 300.0f), 600.0f, 90.0f);
            timeRedEnemy = 0;
        }
    }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

float型のtimeTedEnemyにどんどんTime.deltaTimeを加算していき、

float型のintervalRedEnemyで間隔を入力しています。

クラスのプロパティで「1.0f」と定義したら1秒ごとに生成されます。

if文の最後にはtimeRedEnemyを0にリセットしています。

生成場所は縦方向には画面の外に出る位置で固定して、

横方向にはRandomを使っていろんな場所から出てくるようにしました! 

 

Bullet発射ボタンの設置

 

次に発射ボタンを配置しました。

ボタンがわかりやすくなるように茶色のツールバーの下に

Imageを作成し、その下にボタンを配置してSpriteを貼り付けました。

f:id:sys-bio:20180327031120p:plain

発射ボタンを押してBulletをインスタンス化

最後にGameManagerに

ボタンを押したらBulletが大砲の中から出てくるようにしました。

私としてはここはポイントだと思っているのですが

大砲の位置を動かしても大砲の中からBulletが出てくるようにするために、

インスタンス化したあとBulletを大砲の子オブジェクトにしました!

コードはこんな感じです! cannonが大砲のGameObjectです!

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

public void ButtonRed () {
        redBullet = Instantiate (redBulletPrefab) as GameObject;
        redBullet.transform.parent = cannon.transform;
        redBullet.transform.localPosition = new Vector3 (0.0f, 0.0f, 0.0f);
    }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 真ん中の「redBullet.transform.parent = cannon.transform」で

Bulletを大砲の子オブジェクトにしています!

そうすることで大砲から見た位置をBulletに渡せます!

今回はVector3で全部「0.0f」にすることで

大砲の中心からBulletが出るようにしました。

あとはこのメソッドをボタンに紐づけたら完成です!

 

まとめ

今回の勉強になったポイントは3つあります!

  1. プレハブ化したときのオブジェクトの大きさ
  2. Time.deltaTimeで一定間隔で処理をする
  3. インスタンス化したものを特定の子オブジェクトにする

これは今後も使えそうだなと思いました!

 

次回はBulletとEnemyの当たり判定を認識し、

Scoreが加算されるコードを実装しようと思います!

 

最後まで読んでくださりありがとうございました。