【Unity】2Dシューティングを作ってみる話 #11

記事をご覧いただき、誠にありがとうございます。
投稿主の無能です。

前回は、敵が自動で生成される処理を実装しました。

今回は、敵に画像を設定して、弾を発射出来るようにしたいと思います。

敵の画像を用意する

まずは敵の画像を用意します。

敵はどのようなものを考えているかと言うと、アメーバのようなものが侵略しに来るような感じなので、アメーバで探してみます。

戦闘機やその他、皆さん個人で敵を設定して画像を探してください。

無能が用意した画像はこちらになります。

アメーバ - イラストAC

画像の設定の方法はプレイヤーの設定の時にやりましたね。
あの時の設定方法と同じになります。

このような感じになりました。

Enemyに画像を設定した

予想を遥かに超えて大きい画像だったので、サイズを結構縮小させないといけませんでした。

Pixels Per Unitの値を1024にして丁度良い大きさになった

敵の画像設定が出来たので、次は敵が発射する弾を作ります。

敵の弾を作成する

敵の発射する弾は、このような敵であれば仮のプレイヤーの時に作成した弾で良いと思います。

勿論、敵の感じに合わせて各自弾を作ってください。

このような感じになりました。

新規に作成する場合は、Rigidbody2DとColliderを忘れずにアタッチしましょう。

弾を作成
新規で作成する場合はRigidbody2DとColliderを忘れずにアタッチする

あとはEnemyBulletをプレハブ化します。

EnemyBulletをプレハブ化

あとはHierarchyビューにあるEnemyBulletを削除します。

この時、EnemyをHierarchyビューに出して作業したと思うので、プレハブへの変更の適用を忘れないようにしてください。

変更を適用せずに削除すると、同じ手順を繰り返す羽目になります。

判断の材料としては、Overridesを押すとNo Overridesが表示されて、ボタンが出ていなければ大丈夫です。

プレハブの削除の前には変更が適用されているかを確認

やはり一度やってことのある作業は、繰り返すと早くなっていくものですね。

では敵が弾を発射できる処理を実装します。

敵が弾を発射する処理を実装する

これも何ら難しい事は無くて、プレイヤーの弾の発射の仕組みと同じものになります。

発射ポイントを子オブジェクトに持たせて、そこから弾が出るというものです。

では発射ポイントの作成からやっていきましょう。

空のオブジェクトを作成し「EnemyFirePos」という名前にしたら、Enemyの子オブジェクトにします。

「EnemyFirePos」という空のオブジェクトを作成し、Enemyの子オブジェクトにする

そしたらSprite Rendererを追加して、視認出来るようにします。

そして位置を調整します。

Sprite Rendererを追加して視認出来るようにして位置を調整

では位置が決まったらSprite Rendererを非アクティブにして、EnemyBulletにタグを付けます。

EnemyBulletにタグを付ける

ここまで出来たらHierarchyビューにあるEnemyは不要なので削除します

下準備が出来たのでEnemyCotrollerに処理を追加していきます。

このようになります。
EnemyCotroller.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class EnemyController : MonoBehaviour
{
    [Header("敵の移動スピード")][SerializeField] float moveSpeed = 1f;
    [Header("敵の弾の発射")]
    [SerializeField] GameObject enemyBullet;    // 敵の弾
    [SerializeField] Transform enemyFirePos;    // 発射ポイント
    [SerializeField] float shotSpeed = 5f;      // 弾の速度
    [SerializeField] float shotDelay = 2f;      // 弾の発射の閾値

    Rigidbody2D enemyRB;        // 敵のリジッドボディ
    float shotInterval = 0;     // 弾の発射管理用

    void Start()
    {
        // 敵のリジッドボディを取得
        enemyRB = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 弾の発射 ---
        // deltaTimeを加算
        shotInterval += Time.deltaTime;
        // 発射間隔が閾値未満の場合
        if (shotInterval < shotDelay)
        {
            // 処理を中断
            return;
        }
        // 弾の発射関数を呼ぶ
        EnemyShot(enemyFirePos);
        // 発射間隔をリセット
        shotInterval = 0;
        // --- ここまで
    }

    void FixedUpdate()
    {
        // 敵を動かす
        EnemyMove();
    }

    // 敵を動かす
    void EnemyMove()
    {
        // 敵に左方向のベクトルを持たせる
        enemyRB.velocity = new Vector2(-moveSpeed, 0);
    }

    // 接触判定
    void OnTriggerEnter2D(Collider2D collision)
    {
        // プレイヤーに接触した場合
        if (collision.gameObject.CompareTag("Player"))
        {
            // 接触した方(プレイヤー)を破棄
            Destroy(collision.gameObject);
            // 自身を破棄
            Destroy(gameObject);
        }
        // プレイヤーの弾に接触した場合
        else if (collision.gameObject.CompareTag("PlayerBullet"))
        {
            // 接触した方(プレイヤー)を破棄
            Destroy(collision.gameObject);
            // 自身を破棄
            Destroy(gameObject);
        }
        // ObjectDestroyerに接触した場合
        else if (collision.gameObject.CompareTag("ObjectDestroyer"))
        {
            // 自身を破棄
            Destroy(gameObject);
        }
    }

    // 弾の発射
    void EnemyShot(Transform firePos)
    {
        // 弾を生成
        GameObject bulletClone = Instantiate(enemyBullet, firePos.position, Quaternion.identity);
        // 弾のRigidbodyに速度ベクトルをつける
        bulletClone.GetComponent<Rigidbody2D>().velocity = new Vector2(-shotSpeed, 0);
    }
}
この辺りはプレイヤーと同じ処理なので、説明は割愛します。

少々異なる所と言えば、Enemyが弾を発射する時は自動なので、スペースキーが押された場合という条件が不要ですので、発射の閾値を超えたら即発射するように関数を呼び出しています。

ではEnemyのInspectorビューで設定します。

設定箇所は増えた項目になります。

黄枠が設定箇所

ここまでのEnemyの変更を適用し、HierarchyビューにあるEnemyを削除します。

ではゲームを実行して確認しましょう。

今回確認するのは、敵が弾を発射していること、プレイヤーが敵の弾に当たると破棄されることです。

敵が弾を発射した

敵が弾を発射しました。

しかしプレイヤーが敵の弾に当たっても何ともありません。

敵の弾をすり抜ける

これは、敵の弾に接触した時の処理が無いためです。

ですのでPlayerControllerスクリプトの最後に関数を追記します。
今の状態だとPlayerShotの後に関数を追加する形になると思います。

この関数を追加します。
PlayerController.cs - 追記
private void OnTriggerEnter2D(Collider2D collision)
{
    // 敵の場合
    if (collision.gameObject.CompareTag("Enemy"))
    {
        // 接触した方(敵)を破棄
        Destroy(collision.gameObject);
        // 自身を破棄
        Destroy(gameObject);
    }
    // 敵の弾の場合
    else if (collision.gameObject.CompareTag("EnemyBullet"))
    {
        // 接触した方(敵)を破棄
        Destroy(collision.gameObject);
        // 自身を破棄
        Destroy(gameObject);
    }
}
内容は敵の接触判定と同じですが、ObjectDestroyerに接触した時の処理は不要なので、そこだけが違います。

これで接触時の処理が追加出来たので、ゲームを実行して確認します。

敵の弾に接触したらプレイヤーが消えた

これで処理は問題無さそうです。

ここまでで敵が弾を発射する処理が実装出来ました。

まとめ

今回は
  • 敵と敵の弾の画像を設定した
  • 敵が弾を発射する処理を実装した
という事をやりました。

次回は、敵やプレイヤーが消えるときにただオブジェクトの破棄がされているだけなので、爆発のようなものを作りたいと思います。

では、また次回!

コメント