弾をプレハブ化する
今のところ、実行すると、画面に配置した弾が上に向かって移動して、画面から消えるとゲームオブジェクトも消えるようになっています。ですが弾をあらかじめ配置しておかなければならないのは、コレジャナイ感が半端ないです。今回は実行画面上で弾を生成して、それを連続で撃てるようにしましょう。
自機はもう少し下の方に配置したいので、y座標を-4.5に設定しました。

自機が連続で弾を発射するようにする
プレハブというのは、ゲームオブジェクトの設計図というか模型みたいな物です。敵キャラや弾など、画面に同じような物が何個も出現する場合には、プレハブ化しておくと再利用しやすくなり、便利です。今、画面には自機と弾が一個ずつ配置されています。弾には や が装着されています。この弾のゲームオブジェクトをプレハブ化して再利用しやくすします。
まず、プレハブを入れておくためのフォルダを作ります。Assetsフォルダの中で右クリックして、 → でフォルダを作成します。できたフォルダにはPrefabと名前を付けます。

Prefabフォルダを開いて、ヒエラルキーからBulletのゲームオブジェクトをPrefabフォルダにドラッグ&ドロップします。

すると、Bulletの文字が青く変わりました。これがプレハブになった状態です。

プレハブ化したゲームオブジェクトをスクリプトで生成する
弾は自機から発射されるので、自機のスクリプトの方で弾を生成することにします。自機のスクリプトに以下のように追加します。
public class PlayerControl : MonoBehaviour
{
// このクラスで使う変数など
public GameObject Bullet;
・・・
public GameObject Bulletのように、変数にpublicを付けておくと、インスペクタ上で変数の書き換えができるので便利です。GameObject型のBullet変数を宣言し、インスペクタで編集できるようにしました。ヒエラルキーでPlayerを選ぶと、インスペクタにはこのように表示されました。

ここに、PrefabフォルダからBulletのプレハブを引っ張ってきます。

次にUpdate関数の中に一行を書き加えます。
void Update()
{
Instantiate(Bullet,transform.position,Quaternion.identity);
//左矢印が入力されたら、自機を左に動かす
if (Input.GetKey(KeyCode.LeftArrow)) transform.Translate(-0.05f, 0, 0);
//右矢印が入力されたら、自機を右に動かす
if (Input.GetKey(KeyCode.RightArrow)) transform.Translate(0.05f, 0, 0);
//画面外に移動しないように制限をかける
transform.position = new Vector2(Mathf.Clamp(transform.position.x, -9.71f, 9.71f), transform.position.y);
}
Instantiateはプレハブのインスタンスを作成する処理です。Bulletを自機の位置(transform.position)に作成します。Quaternion.identityは、プレハブを回転せずに配置する時の表現です。
ここで一旦実行してみます。どうなるでしょうか。

一気に大量の弾が出てきました。これはこれでアリかもしれませんが、もう少し発射間隔を空けたくなりました。
そこで、クラスの最初にタイマー代わりの変数を宣言しました。
// このクラスで使う変数など
public GameObject Bullet;
int BulletTimer = 0;
次にUpdate関数に、条件がそろうまで弾の生成をしないように処理を追加しました。具体的には、Update関数が60回呼ばれないと弾は出ません。
void Update()
{
if (++BulletTimer > 60)
{
Instantiate(Bullet,transform.position,Quaternion.identity);
BulletTimer = 0; //弾を発射したらタイマーをリセットする
}
//左矢印が入力されたら、自機を左に動かす
if (Input.GetKey(KeyCode.LeftArrow)) transform.Translate(-0.05f, 0, 0);
//右矢印が入力されたら、自機を右に動かす
if (Input.GetKey(KeyCode.RightArrow)) transform.Translate(0.05f, 0, 0);
//画面外に移動しないように制限をかける
transform.position = new Vector2(Mathf.Clamp(transform.position.x, -9.71f, 9.71f), transform.position.y);
}
これで実行してみます。

一発外れたところに弾があります。これは、最初に画面上に配置した弾ですね。プレハブを作ったので、これはもう不要です。削除してしまいましょう。シーン上のゲームオブジェクトを削除してもプレハブは削除されませんので、安心してください。では、もう一度。

今度はいい感じになりました。
今回の全スクリプトです。
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// このクラスで使う変数など
public GameObject Bullet;
int BulletTimer = 0;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
if (++BulletTimer > 60)
{
Instantiate(Bullet,transform.position,Quaternion.identity);
BulletTimer = 0;
}
//左矢印が入力されたら、自機を左に動かす
if (Input.GetKey(KeyCode.LeftArrow)) transform.Translate(-0.05f, 0, 0);
//右矢印が入力されたら、自機を右に動かす
if (Input.GetKey(KeyCode.RightArrow)) transform.Translate(0.05f, 0, 0);
//画面外に移動しないように制限をかける
transform.position = new Vector2(Mathf.Clamp(transform.position.x, -9.71f, 9.71f), transform.position.y);
}
}
今回はここまでです。お疲れ様でした。
コメント