Unity 6.3 LTS|3D的当てゲームを作ろう④ 敵に弾を撃たせよう

赤い的から敵弾が発射されるUnityの3D的当てゲーム Unity

第4回では、赤い的からPlayerへ向かって敵弾を発射します。弾のPrefab、Rigidbody、一定間隔で発射するコード、衝突した弾を消す処理を順番に作ります。

STEP 1

Playerタグを付けよう

敵弾がPlayerへ当たったことを判定できるように、HierarchyでPlayerを選択し、Inspector上部のTagをPlayerに変更します。

PlayerのTagをPlayerに設定しているInspector
PlayerオブジェクトにはPlayerタグを設定します。Main Cameraではなく、Character Controllerが付いているPlayerを選びます。
POINT|名前とタグは別のもの

オブジェクト名がPlayerでも、TagがUntaggedのままではCompareTag("Player")で見つけられません。

STEP 2

敵弾のPrefabを作ろう

Hierarchyで3D Object → Sphereを作り、名前をEnemyBulletにします。Scaleを(0.1, 0.1, 0.1)程度にし、見やすい色のMaterialを付けます。

Sceneビューで小さな球のEnemyBulletを作っている状態
最初はSceneビューで大きさと色を確認します。

EnemyBulletへRigidbodyを追加し、次のように設定します。

  • Use Gravity:オフ
  • Interpolate:Interpolate
  • Collision Detection:Continuous
EnemyBulletのRigidbody設定
重力を切ることで、弾が下へ落ちずにPlayerへ向かって進みます。

設定したEnemyBulletをHierarchyからProjectウィンドウのAssetsへドラッグし、Prefabにします。

Assets内に作成されたEnemyBullet Prefab
青いキューブの印が付いたらPrefab化できています。Hierarchyに残ったEnemyBulletは削除します。
STEP 3

弾がぶつかったら消えるようにしよう

EnemyBullet.csを作り、Assets内のEnemyBullet Prefabへ追加します。

using UnityEngine;

public class EnemyBullet : MonoBehaviour
{
    public float lifeTime = 5f;

    void Start()
    {
        Destroy(gameObject, lifeTime);
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            Debug.Log("PLAYER HIT");
        }

        Destroy(gameObject);
    }
}
Start生成から5秒後に弾を削除します。
OnCollisionEnter弾が何かにぶつかったときに呼ばれます。
CompareTagぶつかった相手がPlayerか調べます。

今回はPlayerに当たったことをConsoleへ表示します。HPを減らす処理は次回追加します。

STEP 4

敵から弾を発射しよう

EnemyAttack.csを作ります。まずは、弾、Player、発射間隔などをInspectorから設定できるようにします。

public GameObject bulletPrefab;
public Transform player;

public float fireInterval = 2f;
public float bulletSpeed = 5f;
public float spawnOffset = 0.8f;

float fireTimer;

次に、経過時間を数えて、指定した間隔になったらShoot()を呼びます。

void Update()
{
    if (player == null || bulletPrefab == null)
    {
        return;
    }

    fireTimer += Time.deltaTime;

    if (fireTimer >= fireInterval)
    {
        Shoot();
        fireTimer = 0f;
    }
}

Shoot()では敵からPlayerへの方向を計算し、Prefabから弾を作り、Rigidbodyへ速度を設定します。

void Shoot()
{
    Vector3 direction =
        (player.position - transform.position).normalized;

    Vector3 spawnPosition =
        transform.position + direction * spawnOffset;

    GameObject bullet = Instantiate(
        bulletPrefab,
        spawnPosition,
        Quaternion.identity
    );

    Rigidbody bulletRigidbody =
        bullet.GetComponent<Rigidbody>();

    if (bulletRigidbody != null)
    {
        bulletRigidbody.linearVelocity =
            direction * bulletSpeed;
    }
}
EnemyAttack.cs全体を確認する
using UnityEngine;

public class EnemyAttack : MonoBehaviour
{
    public GameObject bulletPrefab;
    public Transform player;

    public float fireInterval = 2f;
    public float bulletSpeed = 5f;
    public float spawnOffset = 0.8f;

    float fireTimer;

    void Update()
    {
        if (player == null || bulletPrefab == null)
        {
            return;
        }

        fireTimer += Time.deltaTime;

        if (fireTimer >= fireInterval)
        {
            Shoot();
            fireTimer = 0f;
        }
    }

    void Shoot()
    {
        Vector3 direction =
            (player.position - transform.position).normalized;

        Vector3 spawnPosition =
            transform.position + direction * spawnOffset;

        GameObject bullet = Instantiate(
            bulletPrefab,
            spawnPosition,
            Quaternion.identity
        );

        Rigidbody bulletRigidbody =
            bullet.GetComponent<Rigidbody>();

        if (bulletRigidbody != null)
        {
            bulletRigidbody.linearVelocity =
                direction * bulletSpeed;
        }
    }
}

赤い的を1つ選んでEnemyAttackを追加し、Bullet PrefabへAssets内のEnemyBullet、PlayerへHierarchyのPlayerをドラッグします。

Enemy AttackにEnemyBulletとPlayerを設定したInspector
Fire Intervalは2、Bullet Speedは5、Spawn Offsetは0.8で試します。
STEP 5

ゲームを動かして確認しよう

Playすると、敵が2秒ごとに小さな弾を作り、Playerの方向へ飛ばします。Play中のHierarchyにはEnemyBullet(Clone)が一時的に表示されます。

赤い的から黒い敵弾が発射されているGameビュー
敵からPlayerへ向かって、小さな黒い弾が飛ぶようになりました。
MISSION

弾に当たり、ConsoleへPLAYER HITと表示されることを確認しよう。壁や床に当たった弾が消えるかも試そう。

弾がその場から動かず、5秒後に消えるとき

Hierarchyへ手動で置いたEnemyBulletには速度が設定されません。Prefabを作ったあと、Hierarchy側のEnemyBulletを削除してください。EnemyAttackが生成したEnemyBullet(Clone)が動く弾です。

Hierarchyに手動配置されたEnemyBullet
このようにHierarchyへ残ったEnemyBulletは削除し、Assets内のPrefabをEnemyAttackへ設定します。
CHALLENGE

敵の強さを調整しよう

  • Fire Intervalを変え、発射間隔を比べよう。
  • Bullet Speedを変え、避けやすさを比べよう。
  • 別の赤い的にもEnemyAttackを追加してみよう。
  • 弾の大きさや色を変更して見やすくしよう。
次回予告

次回はPlayerにHPを追加し、敵弾に当たるとHPが減るようにします。

コメント

タイトルとURLをコピーしました