在 Unity3D 中创建抽象敌人状态机

问题描述 投票:0回答:0

我正在尝试为我的游戏中的敌人行为实现一个可重用的有限状态机,并且正在努力弄清楚如何将派生类作为参数传递。下面是我拥有的两个基本模板类,用于敌人可能拥有的不同状态以及在有限状态机实现中充当上下文的状态管理器。状态管理器脚本附加到敌人的游戏对象,应该包含所有敌人使用的共同行为和数据。

public class EnemyState : MonoBehaviour
{
    protected float stateStartTime;

    public virtual void EnterState(EnemyStateManager enemy)
    {
        stateStartTime = Time.time;
    }

    public virtual void ExitState(EnemyStateManager enemy) {}

    public virtual void UpdateState(EnemyStateManager enemy) {}
}
public class EnemyStateManager : MonoBehaviour
{
    protected EnemyState currentState;
    public float health;

    public virtual void Start() {}

    void Update()
    {
        currentState.UpdateState(this);
    }

    public void SwitchState(EnemyState newState)
    {
        currentState.ExitState(this);
        currentState = newState;
        currentState.EnterState(this);
    }

    public virtual void Attack() {}

    public virtual void Die() {}

    public virtual bool CheckWall() {}

    public virtual bool CheckLedge() {}

    public void SetVelocity(float speed) {}
}

然后我的意图是创建从上述类派生的具体类,以加速设计不同的敌人 AI 行为,这样我就不必重写已经包含在基本模板中并且可以在不同类型之间重用的常见敌人逻辑敌人。

public class SoldierStateManager : EnemyStateManager
{
    public SoldierIdleState IdleState = new SoldierIdleState();
    public SoldierDeadState UnconsciousState = new SoldierUnconsciousState();

    public override void Start()
    {
        base.Start();

        currentState = IdleState;
        currentState.EnterState(this);
    }
}
public class SoldierIdleState : EnemyState
{
    float moveSpeed = 2f;

    public override void EnterState(SoldierStateManager soldier) 
    {
        base.EnterState(soldier);
        soldier.SetVelocity(moveSpeed);
    }

    public override void ExitState(SoldierStateManager soldier) 
    {
        base.ExitState(soldier);
    }

    public override void UpdateState(SoldierStateManager soldier) 
    {
        base.UpdateState(soldier);
        if (soldier.health <= 0)
        {
            soldier.SwitchState(soldier.UnconsciousState);
        }
    }
}
public class SoldierUnconsciousState : EnemyState
{
    float moveSpeed = 0f;
    float unconsciousDuration = 5f;

    public override void EnterState(SoldierStateManager soldier) 
    {
        base.EnterState(soldier);
        soldier.SetVelocity(moveSpeed);
    }

    public override void ExitState(SoldierStateManager soldier) 
    {
        base.ExitState(soldier);
    }

    public override void UpdateState(SoldierStateManager soldier) 
    {
        base.UpdateState(soldier);
        if (Time.time >= stateStartTime + unconsciousDuration)
        {
            soldier.SwitchState(soldier.IdleState);
        }
    }
}

我被卡住了,因为当我尝试实现上面的想法时,我在具体的 State 类中遇到错误,例如:

'SoldierIdleState.EnterState(SoldierStateManager)': no suitable method found to override
在我尝试从基类重写的所有方法中,我猜是因为
EnterState()
的方法签名期望类型为
EnemyStateManager
并且不接受
SoldierStateManager
,即使它是从
EnemyStateManager
.

派生的

有什么方法可以将 EnemyStateManager 子类传递到派生方法中,因为我对 C# 和继承还很陌生,因此感谢任何关于如何完成这项工作的指导。

c# unity3d inheritance subclass game-development
© www.soinside.com 2019 - 2024. All rights reserved.