2021年5月26日6 分

Unityで「シューティングゲーム」をつくろう!Vol.29

前回はスプライトのリストを作成して、複数のアイテムを出現させる効果を実現しました。

今回は2つ目のアイテムとして攻撃の強化を実現させてみます。

現状、スペースキーで1発の弾、Zキーを押すと2発の弾が発射されます。

それを1つにまとめ、通常1発、強化アイテムを取得したタイミング2発撃、3発と攻撃が強化される、といった演出を作ってみます。

今回行うことは次の2つ

1,PlayerController を改造

2,PlayerBuret を改造

3,PlayerTurret を改造 

では早速作っていきましょう。


1、PlayerController の改造

Playerは「アイテムB」を取得した際、通常の単発攻撃から2発の攻撃に変更、さらにその状態で再度「アイテムB」を取得したら3発、さらに6発と4段階で攻撃が強化。逆に攻撃が強化された状態でダメージを受けると、1段階ずつ攻撃力が下がっていく。

フローにすると以下のような感じです。

変数「ShotPower」を作っておき、初期値を1,武器強化アイテムを取得するたびに変数の値を1づつ増やします。

「ShotPower」 が大きいほど強力な攻撃ができるようになるように改造します。

逆にダメージを受けたときに、変数「ShotPower」を1ずつ減らし、攻撃力を下げていきます。

変数「ShotPower」は最大でも4、最小でも1になるようにしておく必要がありますね。

その前に「ShotPower」が3,4 のとき、レーザー同士がぶつかってしまう恐れがあります。

Tagを指定してプログラム側から修正してもいいのですが、今回はUnityエディタ側で修正します。

①Player の Layer に「Player」Layer(作成済み)をセットします。

②この時、子要素(turret)にもLayerを反映させるか聞いてきます。

「Yes change children」を選択します。

③プレイヤーのレーザーのプレハブ(PlayerBulletPrefab)にはすでに「Player」Layerがついていると思います。

一応確認して、ついていなかったら付けておきましょう。

④Project Settings の「Physics 2D」から一番下の「Layer Collision Matrix」を表示させます。

ここはレイヤー同士の当たり判定を有効にするか無効にするか指定する場所です。

Layer「Player」同士が重なるポイントのチェックを外し、Pleyer同士の当たり判定を無効にしておきましょう。

では「PlayerController.cs」を立ち上げて、以下のコードを追加します。

❶まずは変数「shotPower」を宣言、初期値に1を代入しておきます。

❷「ItemB」を取得したときの動きを若干改造します。

まずはインクリメント「shotPower++;」で、ItemBを取得するたびに、変数「shotPower」を1ずつ増やします。

 しかし前述した通り 変数「shotPower」は1から4の間を増減しなければなりません。

 取得した際に4より大きくなったら、つまり5になったら強制的に4に置き換えます。

❸また、変数「shotPower」はダメージを受けた際に、1ずつ減らしていきます。

今度はデクリメント「shotPower--;」で1ずつ減少させます。

また❷と同様に1より小さくなってはいけませんので、1より小さくなったら強制的に1に置き換えます。

Shot()関数を若干修正します。

これまではPlayerが、レーザーに力を与えていました。

このままだとレーザーを複数作るとき、作業量が多くなるので、Playerはレーザー(プレハブ)を作るだけ、レーザーを動かすのは、レーザプレハブ本体にさせましょう。

この後、レーザープレハブのプログラム(PlayerBuret.cs)を、レーザーが前向きに飛ぶように改造します。

❹変数「shotPower」が1のとき、つまり通常攻撃のとき、レーザープレハブを1つだけ生成します。

Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, 0));

その際、向きを Quaternion.Euler(0, 0, 0) つまり素材の向きに指定しています。

❺続いて変数「shotPower」が3のとき、つまりPlayerの先頭からレーザーが3発発射される動きを作成します。

ほぼ❹と同じですが、

Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,20));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,0));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,-20));

とZ軸を中心として、素材の向き、時計回りに20度回転、逆時計回りに20度回転、合計3つのプレハブを生成します。

public int shotPower=1; //❶変数shotPowerを宣言
 

 
void OnTriggerEnter2D(Collider2D collision) //記述済み
 
{
 
if (collision.tag == "Item") //記述済み
 
{
 
string name = collision.GetComponent<SpriteRenderer>().sprite.name;
 
switch (name) //記述済み
 
{
 
case "ItemA": //記述済み
 
SubHP(-1); //記述済み
 
break; //記述済み
 
case "ItemB": //❷
 
shotPower++; //ShotPowerを加算
 
if (shotPower > 4) //4より大きくなったら
 
shotPower = 4; //4 にする
 
break;
 
//以下省略
 
}
 
}}
 

 
void SubHP(int h)
 
{
 
hp -= h; //記述済み
 
HPText.text = "HP:" + hp.ToString(); //記述済み
 
audioSource.PlayOneShot(playerSounds[2]);//記述済み
 
if (hp <= 0) //記述済み
 
{
 
StartCoroutine( Destroy()); //記述済み
 
}
 
else //❸hpが残っていたら
 
{
 
shotPower--; //shotPowerをデクリメント
 
if (shotPower < 1) //1より小さくなったら
 
shotPower = 1; //1に置き換える
 
}
 
}
 

 
void Shot()
 
{
 
if (Input.GetKeyDown(KeyCode.Space) && shotPower == 1) //❹通常攻撃
 
{
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, 0));
 
//bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * shot_speed);//削除
 
audioSource.PlayOneShot(playerSounds[0]); //記述済み
 
}
 

 
if (Input.GetKeyDown(KeyCode.Space) && shotPower == 3) //❺ShotPower3のとき
 
{
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,20));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,0));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0,0,-20));
 
audioSource.PlayOneShot(playerSounds[0]);
 
}
 
if (Input.GetKeyDown(KeyCode.X)&&missilePreparTime>missileTime)
 
{
 
//内部記述済み(省略)
 
}
 
missilePreparTime += Time.deltaTime;
 
}

PlayerControllerはこれで完成です。

2、PlayerBullet の改造

では続いて「PlayerBullet.cs」を改造します。

1,でPlayerは弾を生成するだけに変更しました。

従って弾(PlayerBulletPrefab)自体が生成されたタイミングで速度を持つ必要があります。

❻レーザーの速度を管理する変数「shot_speed」を宣言

❼変数「shot_speed」にについていた

❽Rigidbody2Dコンポーネントを取得して、AddForce()関数で前向きに、shot_speedの力を与えています。

この❻~❽は今までPlayerControllerについていた動き、そのままになります。

❾今回の準備段階で、レイヤー「Player」が付いたもの同士の衝突を無効にしました。従って今までついていた条件文が必要なくなりました。

if (col.tag != "Player" )

この一文とかっこを削除します。
 

float shot_speed; //❻変数宣言(レーザーの速さ)
 
void Start()
 
{
 
shot_speed = 800; //❼速さを指定
 
GetComponent<Rigidbody2D>().AddForce(transform.up * shot_speed);//❽速さを伝える
 
transform.localScale = new Vector3(5, 5, 1);//記述済み
 
Instantiate(shoot_effect, transform.position, Quaternion.identity); //記述済み
 
Destroy(gameObject, 3f);//記述済み
 
}
 

 
void OnTriggerEnter2D(Collider2D col) //❾侵入判定条件を解除
 
{
 
//if (col.tag != "Player" ) //削除
 
//{
 
Instantiate(hit_effect, transform.position, Quaternion.identity);
 
Destroy(gameObject);
 
//}
 
}

PlayerBullet.cs の改造はここまでです。

3、PlayerTurretController の改造

最後はPlayer の両翼についたturretです。

ここからレーザーを発射させることで、2倍の攻撃を実現していましたね。

今まではZキーを押すことでレーザーが発射されましたが、PlayerControllerと同様、スペースキーで発射されます。

PlayerController が持つ変数「shotPower」の値を判定し、攻撃を行いますので、PlayerControllerにアクセスする必要がありますね。

❿PlayerController を使うための変数を宣言します。

⓫ここでは❿で宣言した変数に、PlayerControllerを代入します。

まずは GameObject.Find()関数を使って、Player を探し、そこからGetComponent()関数を使って、PlayerControllerを取得しています。

2段階で探している、というところがポイント。

⓬「shotPower」が2のときの攻撃、これは今までのZキーを押したときの攻撃と同じ動きです。

PlayerController同様、プレハブを生成するだけのプログラムに変更しました。

⓭「shotPower」が4のときの攻撃です。3方向に発射されるので、向きを変えたプレハブを3つ生成しています。

PlayerController playercontroller; //❿PlayerCOntroller を格納する変数
 

 
void Start()
 
{
 
playercontroller = GameObject.Find("Player").GetComponent<PlayerController>(); //⓫
 
audioSource = GetComponent<AudioSource>(); //記述済み
 
}
 

 
void Update()
 
{
 
if(Input.GetKeyDown(KeyCode.Space) && playercontroller.shotPower==2) //⓬
 
{
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, 0));
 
audioSource.Play();
 
}
 
if(Input.GetKeyDown(KeyCode.Space) && playercontroller.shotPower==4) //⓬
 
{
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, 20));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, 0));
 
Instantiate(weapon_prefab, transform.position, Quaternion.Euler(0, 0, -20));
 
audioSource.Play();
 
}
 
if (Input.GetKey(KeyCode.D))
 
{ //省略 }
 
}
 

ちょっと長くなりましたが、今回の課題はこれでいったん完成です。

もっといろいろな強化攻撃があっても面白いですね。

次回はアイテムCの動きを作ってみましょう。

教室では実際に通って頂いての授業の他、ちょっとしたお困りごとに対するオンライン授業やオンラインサポートも行っております。

お困りごとのある方、ご興味がある方は、ぜひお問い合わせください。

お問い合わせは こちら から。

体験授業のお申込みは こちら から。

過去の作品はこちらから。

Vol.20までの作品は、下のVol.21 文末のリンクからどうぞ

Unityで「シューティングゲーム」をつくろう!Vol.21

Unityで「シューティングゲーム」をつくろう!Vol.22

Unityで「シューティングゲーム」をつくろう!Vol.23

Unityで「シューティングゲーム」をつくろう!Vol.24

Unityで「シューティングゲーム」をつくろう!Vol.25

Unityで「シューティングゲーム」をつくろう!Vol.26

Unityで「シューティングゲーム」をつくろう!Vol.27

Unityで「シューティングゲーム」をつくろう!Vol.28

    5