ゲームエンジンⅡ③(2025/10/16)

継承

敵オブジェクトの継承
・メソッドのOverride

                  BaseEnemy
                    ↓
===============================================
↓ ↓
Enemy BossEnemy

継承した場合、親の変数、メソッドを引き継げるが、”private”での宣言では継承されない。
ファミリー外に公開したくない場合は、”protected”で宣言する。
他からアクセスできても問題ないばあいには”public”でOK。

※transfrom.positionとかはMonoBehaviour内で継承されているのでそのまま使える。

メソッドの継承

メソッドのオーバーライド

継承したメソッドを子の側で修正を可能にすること。
親側の関数定義に”virtual”をつける。

親(BaseEnemy.cs)側

    public virtual void OnDamage(int damage)
    {
        health -= damage;
        health = Math.Clamp(health, 0, 100);
    }

子(BossEnemy)側

   public override void OnDamage(float damage)
   {
        if(damage < 100) damage = 0; //100未満のダメージは無効
        base.OnDamage(damage);
   }

(BaseEnemy.cs)

using System;
using UnityEngine;

public class BaseEnemy : MonoBehaviour
{
    public int health = 100;
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {

    }

    //ダメージを受けたときに呼ばれる関数
    public virtual void OnDamage(int damage)
    {
        health -= damage;
        health = Math.Clamp(health, 0, 2000);//helthを0~2000の範囲内に制限
        if(health <= 0)
        {
            OnDeath();
        }
    }
    
    public virtual void OnDeath()
    {
        Destroy(gameObject);
    }
}

(BossEnemy.cs)

using UnityEngine;

public class BossEnemy : BaseEnemy
{
    void Start()    
    {
        
    }

    // Update is called once per frame
    void Update()
    {

    }

    public override void OnDamage(int damage)
    {
        int adjusted = Mathf.CeilToInt(damage * 0.5f);//ダメージ半減
        base.OnDamage(adjusted);
    }
}

(Bullet.cs)

using UnityEngine;

public class Bullet : MonoBehaviour
{
    void Update()
    {
        if (Mathf.Abs(transform.position.y) > 10f) // 画面外に出たら
        {
            Destroy(gameObject);
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        var enemy = collision.GetComponent<BaseEnemy>();
        if (collision.tag.Contains("Enemy"))
        {
            enemy.OnDamage(20);             //enemyにダメージ
            Destroy(collision.gameObject);  //弾丸を消す
        }
    }

}

Enemyをランダム座標(X軸)でInstantiate

using UnityEditor.VersionControl;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    [Header("---Spawn Setting---")]
    public GameObject enemyPrefab;

    [Header("---Spawn Timer")]
    public float timeLimit = 1.0f;
    public float timer = 0.0f;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;//一秒で1になる。
        if (timer >= timeLimit)
        {
            Vector3 randamPosition = transform.position;
            randamPosition.x += Random.Range(-9.0f, 9.0f);

            Instantiate(enemyPrefab, RandomPosition, Quaternion.identity);
            timer = 0.0f;
        }
    }
}

SpawnerをコピーしてBossSpawnerとする。
EnemyPrefabをEnemy1に変更。

StateMachine(状態遷移)

enum(列挙型) – switch が簡単で実装しやすい。
今回はBossEnemyの行動を状態遷移で変えていく。
(enumで定義する例)

    public enum BossState
    {
        Idle = -1, //省略すると内部的に1から始まる
        Attack     //内部的に0
        Enrage     //内部的に1
    }

・状態遷移
①状態を作る(今回はenumで定義)
②状態を実装(メソッドを実装)
③switch文で切り替え

    public enum BossState
    {
        Appear, //出現
        Idle,   //待機
        Attack_01,  //攻撃1:ばらまき射撃
        Attack_02,  //攻撃2:集中攻撃
        Dead,       //死亡
    }
    public BossState currentState;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   void Update()
    {
        switch(currentState)
        {
            case BossState.Appear:
                Appear();
                break;

            case BossState.Idle:
                Idle();
                break;

            case BossState.Attack_01:
                Attack_01();
                break;

            case BossState.Attack_02:
                Attack_02();
                break;
        }
    }

    public void Appear()
    {

    }

    public void Idle()
    {

    }

    public void Attack_01()
    {

    }

    public void Attack_02()
    {

    }
    
    public void Death()
    {
        
    }

メソッドの中身は次回。

コメント

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