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」には次のコードを記述します。
⑩まずは変数用意の部門から。
・ この「Asteroid」に当たった時、または爆発したときにエフェクト[explosion]を指定します。
・つづいて隕石画像を複数用意したいので、Sprite型の配列[sprites]を準備しておきましょう。
この2つは後ほど「Asteroid」の inspector から指定します。
・さらにこのSprite をコントロールするため「SpriteRenderer型」の変数[ast_Renderer]を用意しておきます。
・大きさも毎回変えたいと思いますので、大きさの係数を入れる小数点型の変数[scale]を指定。
これで変数の指定は完成です。
⑪つづいて Start()関数で生成されるときの処理を作ります。
ast_Renderer = GetComponent<SpriteRenderer>() でSpriteRendererを取得します。
取得した[ast_Renderer] のSprite(見た目)に配列から取得する乱数番目の画像を指定します。この画像は後ほど指定します。
変数[scale]を乱数で指定します。3倍から8倍の大きさになります。
つづいて transform.localScale で大きさを指定します。
最後はちょっと長いですね?
GetComponent<Rigidbody2D>().velocity = new Vector2(Random.Range(-3, 3), Random.Range(-3f, -1f));
先にRigidbody2Dコンポーネントの情報を取得して、velosity(速度)に、x方向、y方向、それぞれの乱数で取得した力を与えます。
[SerializeField] GameObject explosion; //爆発
public Sprite[] sprites; //Sprite型の配列変数を宣言
private SpriteRenderer ast_Renderer; //SpriteRenderer型の変数を宣言
float scale; //大きさの係数
void Start()
{
ast_Renderer = GetComponent<SpriteRenderer>(); //SpriteRenderer を取得
ast_Renderer.sprite = sprites[Random.Range(0, 6)]; //乱数で画像を指定
scale = Random.Range(3.0f, 8.0f); //大きさ係数を乱数で決定
transform.localScale = new Vector3(scale, scale, 1); //大きさを指定
GetComponent<Rigidbody2D>().velocity = new Vector2(Random.Range(-3, 3), Random.Range(-3f, -1f)); //速度を与える
}
続いて「Asteroid」の inspector から、Scriptの部分を確認します。
⑫変数で宣言した[Explosion]には以前作成したExplosionプレハブを指定します。
⑬配列[sprites]のSize(数)には6を指定します。
そうすることで、6個の窓ができたと思います。今回はこの1つ1つに6種類の隕石の画像をセットします。
これで動かしてみましょう。まずはスタートと同時に隕石が発生し、下に向かって動き出すと思います。毎回違う大きさや違う種類の隕石が出ますよね?
この後は隕石にミサイルが当たると爆発する動きを作りたいのですが、ちょっと長くなったので今回はここまで。
記述だけではわからない、詳しく聞きたいという方は是非ご連絡ください。
教室では実際に通って頂いての授業の他、全国対応可能なオンライン授業やオンラインサポートも行っております。
お困りごとのある方、ご興味がある方は、ぜひお問い合わせください。
お問い合わせは こちら から。
体験授業のお申込みは こちら から。
過去の「Unityで作るシューティングゲーム」はこちらから。
Comments