You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity可复用状态机泛型抽象类及构造器问题排查与重构

问题描述

我正尝试在Unity中实现一款支持普通状态与层级状态的可复用状态机,定义了BaseState、StateMachine、StateFactory三个核心抽象类。

BaseState

public abstract class BaseState<EState>
        where EState : Enum
    {
        protected StateFactory<EState, BaseState<EState>> _factory;
        protected StateMachine<EState, BaseState<EState>> _machine;

        protected EState _stateKey;

        public BaseState(EState stateKey, StateMachine<EState, BaseState<EState>> machine, StateFactory<EState, BaseState<EState>> factory)
        {
            _stateKey = stateKey;
            _machine = machine;
            _factory = factory;
        }

        //无关逻辑
    }

HierarchicalBaseState

public abstract class HBaseState<EState> : BaseState<EState> where EState : Enum
    {
        //是否为根状态
        protected bool _isRootState = false;

        //当前状态的父状态与子状态引用
        protected HBaseState<EState> _parentState;
        protected HBaseState<EState> _childState;

        public HBaseState(EState stateKey, StateMachine<EState, HBaseState<EState>> machine, StateFactory<EState, HBaseState<EState>> factory, bool isRootState = false) : base(stateKey, machine, factory)
        {
            _stateKey = stateKey;
            _isRootState = isRootState;
        }
        
        //无关逻辑
    }

StateMachine

public abstract class StateMachine<EState, StateType> : MonoBehaviour 
        where EState : Enum
        where StateType : BaseState<EState>
    {
        protected StateFactory<EState, StateType> _factory;

        public StateType _currentState;

        //无关逻辑
    }

StateFactory

public abstract class StateFactory<EState, StateType> : MonoBehaviour
    where EState : Enum
    where StateType : BaseState<EState>
    {
        protected StateMachine<EState, StateType> _machine;

        protected Dictionary<EState, StateType> _statesCached = new Dictionary<EState, StateType>();

        public StateFactory(StateMachine<EState, StateType> machine, bool cacheStates = true)
        {
            _machine = machine;
            InstantiateStates();
        }

        protected abstract void InstantiateStates();

        //无关代码
    }

核心问题

编写继承自BaseState的层级状态类HBaseState构造器时,C#无法将StateMachine<EState, HBaseState<EState>>转换为StateMachine<EState, BaseState<EState>>,导致无法将参数传递给基类BaseState的构造器,强制类型转换也无效。

请问我的泛型实现是否正确?该如何重构代码以解决此问题?


解决方案

问题根源

你的泛型设计存在不变性约束问题:StateMachine<EState, StateType>是泛型类,C#中泛型类默认是不变的——即使HBaseState<EState>继承自BaseState<EState>,StateMachine<EState, HBaseState<EState>>也不能被视为StateMachine<EState, BaseState<EState>>的子类,两者属于完全不同的类型,因此无法直接转换。

重构方案:让BaseState支持泛型状态类型

修改BaseState的定义,引入第二个泛型参数StateType,让基类能够适配不同的状态子类,解决类型不兼容问题。

1. 修改BaseState类

public abstract class BaseState<EState, StateType>
    where EState : Enum
    where StateType : BaseState<EState, StateType>
{
    protected StateFactory<EState, StateType> _factory;
    protected StateMachine<EState, StateType> _machine;

    protected EState _stateKey;

    public BaseState(EState stateKey, StateMachine<EState, StateType> machine, StateFactory<EState, StateType> factory)
    {
        _stateKey = stateKey;
        _machine = machine;
        _factory = factory;
    }

    //无关逻辑
}

2. 修改HBaseState类

让HBaseState继承自新的BaseState,并指定自身为StateType参数:

public abstract class HBaseState<EState> : BaseState<EState, HBaseState<EState>> where EState : Enum
{
    protected bool _isRootState = false;
    protected HBaseState<EState> _parentState;
    protected HBaseState<EState> _childState;

    public HBaseState(EState stateKey, StateMachine<EState, HBaseState<EState>> machine, StateFactory<EState, HBaseState<EState>> factory, bool isRootState = false) 
        : base(stateKey, machine, factory)
    {
        _isRootState = isRootState;
        // 无需重复赋值_stateKey,基类构造器已处理
    }
    
    //无关逻辑
}

3. 调整StateMachine的约束

确保StateMachine的StateType约束匹配新的BaseState定义:

public abstract class StateMachine<EState, StateType> : MonoBehaviour 
    where EState : Enum
    where StateType : BaseState<EState, StateType>
{
    protected StateFactory<EState, StateType> _factory;
    public StateType _currentState;

    //无关逻辑
}

4. 调整StateFactory的约束

同样更新StateFactory的泛型约束:

public abstract class StateFactory<EState, StateType> : MonoBehaviour
    where EState : Enum
    where StateType : BaseState<EState, StateType>
{
    protected StateMachine<EState, StateType> _machine;
    protected Dictionary<EState, StateType> _statesCached = new Dictionary<EState, StateType>();

    public StateFactory(StateMachine<EState, StateType> machine, bool cacheStates = true)
    {
        _machine = machine;
        InstantiateStates();
    }

    protected abstract void InstantiateStates();

    //无关代码
}

额外优化建议

  • 去掉HBaseState构造器中重复的_stateKey赋值,基类构造器已完成该操作,避免冗余。
  • 如果需要支持普通非层级状态,可以新增SimpleBaseState<EState>类,继承自BaseState<EState, SimpleBaseState<EState>>,保持状态机的扩展性。

内容的提问来源于stack exchange,提问作者Vinh Nguyễn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:37:50