Unityで作る「シューティングゲーム」前回の課題でミサイルを撃つ動きを作ることができました。ミサイルを撃っただけではつまらない。ターゲットとなるものが欲しいですよね?ということで今回は隕石を作ってみたいと思います。
その前に、前回作成したミサイルの動き、一部修正を行います。
Step:1 ミサイルのスクリプトを修正
まず、前回ミサイルがうまく出なかった、またはエラーになったという症状がでているかもしれません。プレハブで使用したミサイルのプログラム、既存のものを使っていたからですね。先にその生成を行います。
ミサイルプレハブについてあるスクリプトを下のように改造しましょう
public GameObject shoot_effect;
public GameObject hit_effect;
void Start()
{
Instantiate(shoot_effect, transform.position, Quaternion.identity); //Spawn muzzle flash
Destroy(gameObject, 3f);
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag != "Projectile")
{
Instantiate(hit_effect, transform.position, Quaternion.identity);
Destroy(gameObject);
}
}
どうでしょうか?ミサイル、飛ぶようになりましたか?
Step:2 マシンの動きの改造
つづいてプレイヤーの動きをちょっと調整してみましょう。現状、左右にしか動きませんよね?しかも画面の外側に出てしまいます。今回改造するポイントはこの2つ。
前後の動きの実装
前後左右の移動制限
では早速作っていきましょう!
今回はいきなりスクリプトファイルを修正していきますよ。作成済みの「PlayerController.cs」を開いて、以下のコードを修正します。
今までは Update()関数 の中にすべての動きを作っていましたが、1つ1つの動きを関数化してしまい、Update()関数 の中ではそれぞれの関数を起動させていきます。
①まずは前後左右の動きを管理する Move()関数 を作ります
/*Playerの動き*/
private void Move()
{
playerRb2d.velocity *= 0.995f; //減速
if (Input.GetKey(KeyCode.LeftArrow)) //左キーを押したとき
{
playerRb2d.AddForce((-transform.right) * acceleration); //左向きの速度を与える
}
if (Input.GetKey(KeyCode.RightArrow)) //右キーを押したとき
{
playerRb2d.AddForce((transform.right) * acceleration); //右向きの速度を与える
}
if (Input.GetKey(KeyCode.UpArrow)) //上キーを押したとき
{
playerRb2d.AddForce((transform.up) * acceleration); //上向きの速度を与える
}
if (Input.GetKey(KeyCode.DownArrow)) //下キーを押したとき
{
playerRb2d.AddForce((-transform.up) * acceleration); //下向きの速度を与える
}
}
ここはそれほど難しくないですよね?先に以前学習したスピードを減速するプログラムを指定しています。その後は左右の動きをコピペで持ってきます。
上向き矢印キーを押したときの動きと下向き矢印キーを押したときの動きを追加しただけですね?
②つづいて移動制限の動きです。下の図からもわかるように、背景の大きさ、また画面の横の大きさは、おおよそ-19~19の範囲に収まりそうです。ということでプレイヤーの左右の移動制限を-19 ~19 程度にしておきましょう。

右の動きを例に説明すると、もしプレイヤーのx座標の大きさが19を超えたら、強制的に19に戻す、というプログラムを作ればよさそうですね?また、左右の境界線についた時、例えば19の境界線についた時、プレイヤーはまだ右向きの速度を持っています。左側に移動するためには左キーを押して、X方向の速度をプラスからマイナスに変える必要があります。プラスからマイナスに持ってくるのに時間がかかるので、X方向の速度をいったんリセットします。
同様に、左の動き、前後の動きを作ってみましょう。前の境界線は8、後ろの境界線は-8ぐらいがよさそうです。
この動きを Restrictions() という名前で関数化します。
/*移動制限*/
void Restrictions()
{
if (transform.position.x > 19) //右の移動制限
{
transform.position = new Vector3(19, transform.position.y, 0);
playerRb2d.velocity = new Vector2(0, playerRb2d.velocity.y);
}
if (transform.position.x < -19) //左の移動制限
{
transform.position = new Vector3(-19, transform.position.y, 0);
playerRb2d.velocity = new Vector2(0, playerRb2d.velocity.y);
}
if (transform.position.y > 8) //上の移動制限
{
transform.position = new Vector3(transform.position.x, 8, 0);
playerRb2d.velocity = new Vector2(playerRb2d.velocity.x, 0);
}
if (transform.position.y < -8) //下の移動制限
{
transform.position = new Vector3(transform.position.x, -8, 0);
playerRb2d.velocity = new Vector2(playerRb2d.velocity.x, 0);
}
}
③前回作ったミサイルを撃つ動きも Shot()という名前で関数化してしまいます。
/*ミサイルを撃つ*/
void Shot()
{
if (Input.GetKeyDown(KeyCode.Space)) /*スペースキーが押されたら*/
{
GameObject bullet = Instantiate(weapon_prefab, transform.position, transform.rotation); /*ミサイルを生成*/
bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * shot_speed); /*ミサイルに速度を与える*/
}
}
④さてこれでプレイヤーの3つの関数ができました。後はこの3つをUpdate()関数の中で呼び出せばよさそうですね?
void Update()
{
Move();
Restrictions();
Shot();
}
これでプレイヤーのプログラムの改造は完成です。
Step:3 隕石の作成
まずは隕石のスプライトを準備しましょう。
⑤アセットストアから取得済みの隕石画像(Asteroid)をドラッグ&ドロップで Hierarchyに配置します。今回はプログラムから6種類の隕石をランダムで出現させるという動きを作りますので、どの画像でもいいです。

⑥取り込んだ隕石画像の名前を修正、「Asteroid」にしておきましょう。
SpriteRendorere の SortingLayer に「Enemy」というレイヤーを作成して割り当てます。
「Enemy」は「Pleyer」の上、つまり後ろに配置されるようにしておきます。

⑦「Rigidbody 2D」コンポーネントを追加します。
Gravity Scale の値を0にします。これは重力に相当するものでしたよね。
⑧つづいて「Circle Collider 2D」コンポーネントを追加します。
Edit Collider を押してCollider の大きさを調整しておきましょう。

⑨ではこの「Asteroid」の動きを管理するプログラムを作っていきます。
「Asteroid.cs」というスクリプトファイルを作って、「Asteroid」にアタッチします。
「Asteroid.cs」には次のコードを記述します。
⑩まずは変数用意の部門から。