Unity:敵機のHPと弾の攻撃力とアニメーション~公式チュートリアル 2Dシューティングに挑戦

Unity公式サイトに掲載されているチュートリアルの2Dシューティングに挑戦。今回は敵機のHPと弾の攻撃力、アニメーションのステップを行いました。チュートリアルを進めながら変更した箇所などをピックアップしています。

前回の記事はこちら
Unity:プレイヤーの移動制限とタイトル作成~公式チュートリアル 2Dシューティングに挑戦

エネミーのHP、弾の攻撃力、アニメーションの追加

チュートリアルページ:エネミーのHP、弾の攻撃力、アニメーションの追加
このステップの手順は次の通りです。

  1. HP(ヒットポイント)と攻撃力(power)の実装
  2. ダメージを受けた時の表現
  3. プレイヤーの無敵時間

ヒットポイントが0になった時に爆発させる

チュートリアルのこの部分の手順で書かれているスクリプト Enemy のコードの中で Bulletコンポーネントを取得する部分について、エラーが発生したので修正しました。スクリプトのマーカー部分になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    // スクリプト Spaceship コンポーネントを格納する変数
    Spaceship spaceship;
    // ヒットポイントを格納する変数(初期値 1)
    public int hp = 1;

    // ゲームのスタート時の処理
    void Start()
    {
        // Spaceship コンポーネントを取得
        spaceship = GetComponent<Spaceship>();
        // ローカル座標のY軸のマイナス方向(画面上から下)に移動する
        spaceship.Move(transform.up * -1);
        // 弾の発射処理(コルーチン Shot )を実行
        StartCoroutine("Shot");
    }

    // トリガーに入った時の処理
    // 衝突した相手の Collider2D コンポーネントを引数 c に格納
    void OnTriggerEnter2D(Collider2D c)
    {
        // レイヤー名を取得して layerName に格納
        string layerName = LayerMask.LayerToName(c.gameObject.layer);
        // レイヤー名がBullet (Player)以外の時は何も行わない
        if (layerName != "Bullet (Player)") return;
        // 弾オブジェクトの Transform コンポーネントの取得
        // 衝突した相手の Collider2D コンポーネントの親(オブジェクト)の
        // Transform コンポーネントを取得して playerBulletTransform に格納
        Transform playerBulletTransform = c.transform.parent;
        // スクリプト Bullet コンポーネントを取得して bullet に格納
        Bullet bullet = playerBulletTransform.GetComponent<Bullet>();
        // ヒットポイントを減らす
        // 変数 hp からスクリプト Bullet コンポーネントの変数 power を引いた結果を hp に渡す
        hp = hp - bullet.power;
        // 弾の削除
        Destroy(c.gameObject);
        // ヒットポイントが0以下であれば
        if (hp <= 0)
        {
            // 爆発処理
            // スクリプト Spaceship の関数 Explosion() を実行
            spaceship.Explosion();
            // エネミーの削除
            Destroy(gameObject);
        }
    }

    // 弾の発射処理(コルーチン)
    IEnumerator Shot()
    {
        // canShotがfalseの場合、ここでコルーチンを終了させる
        if (spaceship.canShot == false)
        {
            yield break;
        }
        while (true)
        {
            // 子要素を全て取得する
            for (int i = 0; i < transform.childCount; i++)
            {
                // Transformコンポーネント shotPosition を作成して子要素を格納
                Transform shotPosition = transform.GetChild(i);
                // 弾をプレイヤーと同じ位置/角度で作成
                spaceship.Shot(shotPosition);
            }
            // shotDelay 秒待つ
            yield return new WaitForSeconds(spaceship.shotDelay);
        }
    }
}

チュートリアルではプレハブ Wave > Enemy の コンポーネント Enemy (Script) > Hp の値を10 に指定していましたが、動作確認してみると、すぐに破壊できてしまうので 20 に増やしてみました。

スクリプトからトリガーのセット

スクリプト Spaceship にコメントを追加したものがこちら。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Rigidbody2Dコンポーネントを必須にする
[RequireComponent(typeof(Rigidbody2D))]

public class Spaceship : MonoBehaviour
{
    // 機体の移動スピードを格納する変数
    public float speed;
    // 弾を撃つ間隔を格納する変数
    public float shotDelay;
    // 弾のプレハブを格納する変数
    public GameObject bullet;
    // 弾を撃つかどうかのフラグ
    public bool canShot;
    // 爆発のプレハブを格納する変数
    public GameObject explosion;
    // Animator コンポーネントを格納する変数
    private Animator animator;
    // Rigidbody2D コンポーネントを格納する変数
    private Rigidbody2D rb;

    // ゲーム起動時の処理
    void Awake()
    {
        // Animator コンポーネントを取得して変数 animator に格納
        animator = GetComponent<Animator>();
        // Rigidbody2D コンポーネントを取得して変数 rb に格納
        rb = GetComponent<Rigidbody2D>();
    }

    // 爆発を作成する処理
    public void Explosion()
    {
        // 爆発をオブジェクトと同じ位置/角度で作成
        Instantiate(explosion, transform.position, transform.rotation);
    }

    // 弾を作成する処理
    public void Shot(Transform origin)
    {
        // 弾を引数 origin と同じ位置/角度で作成
        Instantiate(bullet, origin.position, origin.rotation);
    }

    // 機体の移動処理
    public void Move(Vector2 direction)
    {
        // Rigidbody2D コンポーネントの velocity に方向と移動速度を掛けた値を渡す
        rb.velocity = direction * speed;
    }

    // Animator コンポーネントを他のスクリプトから参照する処理
    public Animator GetAnimator()
    {
        // 処理を実行すると animator を出力する
        return animator;
    }
}

スクリプト Enemy にコメントを追加したものがこちら。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    // スクリプト Spaceship コンポーネントを格納する変数
    Spaceship spaceship;
    // ヒットポイントを格納する変数(初期値 1)
    public int hp = 1;

    // ゲームのスタート時の処理
    void Start()
    {
        // Spaceship コンポーネントを取得
        spaceship = GetComponent();
        // ローカル座標のY軸のマイナス方向(画面上から下)に移動する
        spaceship.Move(transform.up * -1);
        // 弾の発射処理(コルーチン Shot )を実行
        StartCoroutine("Shot");
    }

    // トリガーに入った時の処理
    // 衝突した相手の Collider2D コンポーネントを引数 c に格納
    void OnTriggerEnter2D(Collider2D c)
    {
        // レイヤー名を取得して layerName に格納
        string layerName = LayerMask.LayerToName(c.gameObject.layer);
        // レイヤー名がBullet (Player)以外の時は何も行わない
        if (layerName != "Bullet (Player)") return;
        // 弾オブジェクトの Transform コンポーネントの取得
        // 衝突した相手の Collider2D コンポーネントの親(オブジェクト)の
        // Transform コンポーネントを取得して playerBulletTransform に格納
        Transform playerBulletTransform = c.transform.parent;
        // スクリプト Bullet コンポーネントを取得して bullet に格納
        Bullet bullet = playerBulletTransform.GetComponent();
        // ヒットポイントを減らす
        // 変数 hp からスクリプト Bullet の変数 power を引いた結果を hp に渡す
        hp = hp - bullet.power;
        // 弾の削除
        Destroy(c.gameObject);
        // ヒットポイントが0以下であれば
        if (hp <= 0)
        {
            // 爆発処理
            // スクリプト Spaceship の関数 Explosion() を実行
            spaceship.Explosion();
            // 敵機の削除
            Destroy(gameObject);
        }
        //上記以外の場合
        else
        {
            // アニメーションステートの遷移
            // スクリプト Spaceship の関数 GetAnimator() を実行し
            //Animator コンポーネント のトリガー Damage をセット
            spaceship.GetAnimator().SetTrigger("Damage");
        }
    }

    // 弾の発射処理(コルーチン)
    IEnumerator Shot()
    {
        // canShotがfalseの場合、ここでコルーチンを終了させる
        if (spaceship.canShot == false)
        {
            // 処理の停止
            yield break;
        }
        // 繰り返し処理
        while (true)
        {
            // 子要素(弾の発射位置のオブジェクト)を全て取得する
            for (int i = 0; i < transform.childCount; i++)
            {
                // Transform コンポーネント shotPosition を作成して子要素を格納
                Transform shotPosition = transform.GetChild(i);
                // 弾をプレイヤーと同じ位置/角度で作成
                // スクリプト Spaceship の関数Shot() を実行
                spaceship.Shot(shotPosition);
            }
            // スクリプト Spaceship の 変数 shotDelayの値の時間処理を中断
            yield return new WaitForSeconds(spaceship.shotDelay);
        }
    }
}

アニメーションの作成

自機(Player)の Animator コンポーネントの トランジョン設定はこのように Transion Duration の値を 0 にしました。

自機(Player)の [Animation]ウィンドウの 編集内容を [Curve]編集モードに切り替えて確認するとこのようになります。

WebGL

ここまでの内容を動作確認用にWebGLでビルド。自機登場や敵機に弾が当たるエフェクトが追加されたのでグッとゲームらしくなってきました。
画像クリックで再生(ファイルサイズ:約7MB)

スポンサーリンク
スポンサーリンク

スポンサーリンク

フォローする