前回は「中ボス」の外観と中ボスのタレットを作成しました。今回はまずはタレットの動きを管理するプログラムを作っていきます。
では早速作っていきます。
1,中ボスタレットのプログラム
まずタレットの動きの要件ですが、
1、通常は中ボスの上で回転しながら、不定期でミサイルを発射する
2、HPを持っていて、特定回数ダメージを受ければ破壊される
この動きを実現するために、プログラミングを作成していきます。
前回最後に作成したスクリプトファイル、[EnemyStationATurret] を立ち上げて以下のコードを記述してください。
変数には要件を実現するために必要な「HP」「弾を発射する間隔」それと「弾の速さ」を指定します。
またゲームオブジェクトとして「発射する弾」と「HPが0になったとき爆発するエフェクト」この2つを指定します。
❶弾を発射する関数ですが、発射する間に時間を持つため、「コルーチン」を使用します。
while() 関数で「発射」と「待機時間」を繰り返します。「待機時間」は「Random.Range」を使って0.5秒から4秒の乱数秒に指定します。
弾は「Instantiate()関数」を使って生成、オブジェクト化しておき、「AddForce()関数」で直接速度を与えています。
❷イベント関数「OnTriggerEnter2D()」でプレイヤーの弾との当たり判定を行っています。プレイヤーの弾が当たるたびにHPを1ずつ減らし、HPが0になったら爆発のエフェクトを生成し、自分自身を削除しています。
❸Update関数内では、 transform.Rotate()関数を使ってタレットをぐるぐる回しています。
int hp; //ヒットポイント
float shot_speed; //弾の速さ
float shotDelay; //弾を撃つ間隔
[SerializeField] GameObject EnemyBullet; //EnemyBulletを格納
[SerializeField] GameObject explosion; //爆発エフェクト
//❶弾を生成するコルーチン型関数
IEnumerator Shot()
{
yield return new WaitForSeconds(1); //仮の待ち時間
while (true) //ずっとこの内部の同じ動きを繰り返す
{
shotDelay = Random.Range(0.5f, 3f); //発射の間隔を0.5~4秒の乱数
yield return new WaitForSeconds(shotDelay); //指定した間隔待って次の処理へ
//弾を生成するプログラム
GameObject bullet = Instantiate(EnemyBullet, transform.position, transform.rotation);
//弾に速さを与えるプログラム
bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * shot_speed);
}
}
//❷ダメージ判定のイベント関数
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Projectile" ) //Player の攻撃に当たったら
{
Destroy(collision.gameObject); //弾の削除
hp--; //hp を1ずつ減らす
if (hp == 0) //HPが0になったら
{
//爆発のエフェクトを生成
GameObject effect = Instantiate(explosion, transform.position, transform.rotation);
Destroy(effect, 1.5f); //爆発エフェクトの削除
Destroy(gameObject); //Enemyの削除
}
}
}
void Start()
{
hp = 50; //hp の初期値を50に指定
shot_speed = 800; //ショットスピードを800に指定
StartCoroutine(Shot()); //ショットコルーチンを発動
}
void Update()
{
transform.Rotate(new Vector3(0, 0, 0.1f)); //❸ずっと回転
}
Unityエディタで「TurretLargeRight」に移ると、スクリプトファイルに2つの変数(オブジェクト)を入れる枠ができています。
①下の図のようにそれぞれ EnemyBUlletPrefab、 Explosion1 を指定しておきます。
Explosion1プレハブですが、うまく表示されないという不具合があるようです。
以下のように修正しておきます。
②「Explosion1プレハブ」を選択、Inspector から 「Particle System」コンポーネントの下側にある「SortingLayerID」にすでに作成している「Turret」を指定してあげます。
これで爆発演出が一番上に表示されるはず。
ではこれで動かしてみましょう。下の図のように、タレットからミサイルが発射されているのがわかると思います。(ちょっとわかりにくいかもしれません)
さらにゲームを続けると、プレイヤーの撃った弾、敵が撃った弾が中ボスに当たってしまい、タレットを攻撃することができないようです。そこで次のようなルールを設けたいと思います。
・Playerの弾は中ボスに当たらない
・Enemyの弾も中ボスに当たらない
ではどうやってこれを実現させればよいでしょうか?
現状、Playerの弾には次のようなコードが記述されています。
void OnTriggerEnter2D(Collider2D col){
if (col.gameObject.tag != "Projectile") {
Instantiate(hit_effect, transform.position, Quaternion.identity);
Destroy(gameObject); } }
当たった対象のゲームオブジェクトが持っているタグが、"Projectile" でなければ自分自身を削除する、というプログラミングです。
ここに「または」で他のタグを追加していってもいいのですが、今回は別の方法を学習します。
まず、登場人物に「Layer」を追加します。
③どのオブジェクトでもいいので、まずは「Layer」を選択し、一番下に表示される「Add Layers」をクリックします。
④今回登場する3種類のオブジェクト用に、以下の3つのLayerを作成します。
「Player」「Enemy」「EnemyStation」
⑤まずは「EnemyStation」を選択し、Inspectorの「Layer」に上で作成した「EnemyStation」を指定します。
英語で子要素にもそのLayerを加えるか聞いてきます。今回は子要素にはつけないので「No,this objekt only」を選択します。
⑥同様にプレハブの「PlayerBulletPrefab」を選択し、Layer「Player」を追加
⑦プレハブの「EnemyBulletPrefab」また、「Enemy2Vullet」を選択し、Layer「Enemy」を追加
これでレイヤーの準備ができました。
続いてそれぞれのLayerが他のLayerに影響を与えるかどうかを指定します。
⑧上部メニューの「Edit」から「Project Settings」を選択。
「Physics2D」の下部、「Layer Collision Matrix」を選択。
「EnemyStation」と「Player」「Enemy」が交わる部分のチェックを外します。
ではこの状態で起動させてみましょう。
うまくいったら、スクリプトファイル[EnemyStationATurret] を残りの2つのタレット「Turret Large Left」「Turret Large Center」にも追加し、オブジェクト変数に各プレハブをセットしておきましょう。
だいぶ難しいゲームができてきました。
みなさん、ついてきているかな??
今回はここまで、次回は中ボスを動かしてみましょう。
教室では実際に通って頂いての授業の他、ちょっとしたお困りごとに対するオンライン授業やオンラインサポートも行っております。
お困りごとのある方、ご興味がある方は、ぜひお問い合わせください。
お問い合わせは こちら から。
体験授業のお申込みは こちら から。
過去の作品はこちらから。
Vol.01~Vol.10 は下のVol.11 文末のリンクからどうぞ
Comments