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

Unity中C#有限状态机字典仅存Null值问题求助

问题排查与解决方案

1. 先确认字典实例是否真的为空

你当前的Debug.Log(states)只会打印字典对象本身,无法看到内部键值对的实际内容。修改日志代码,遍历字典打印每个状态实例:

foreach (var stateEntry in states)
{
    Debug.Log($"状态类型: {stateEntry.Key.Name}, 实例是否为空: {stateEntry.Value == null}");
}

这一步能明确是创建字典时实例就为空,还是后续GrabAllStates方法处理时导致的空值。

2. 检查状态子类的构造函数

如果遍历后发现创建时实例就为空,大概率是状态子类的构造函数存在问题:

  • 确保所有状态子类(如RoamingState、IdleState等)的构造函数是公共无参构造,没有私有/保护访问限制;
  • 检查构造函数内部是否有异常代码(比如访问未初始化的对象、调用不存在的方法),这类异常会导致实例化失败,Unity控制台会抛出报错信息,仔细查看控制台日志。

示例正确的状态子类构造:

public class RoamingState : EmptyState
{
    // 公共无参构造,确保能正常实例化
    public RoamingState()
    {
        // 构造逻辑,避免空引用操作
    }
}

3. 检查EmptyState基类定义

确认EmptyState是非抽象类(如果是抽象类,子类必须实现所有抽象成员,但实例化子类本身是允许的,除非子类未完成实现),且没有限制实例化的逻辑(比如私有构造函数)。

4. 排查GrabAllStates方法的实现

如果原字典实例正常,但FSM内的字典为空,问题出在状态复制逻辑:

  • 确保AmalgamFSM内的目标字典已初始化,比如:
    public class AmalgamFSM : MonoBehaviour
    {
        private Dictionary<Type, EmptyState> _fsmStates = new Dictionary<Type, EmptyState>();
    
        public void GrabAllStates(Dictionary<Type, EmptyState> sourceStates)
        {
            // 清空原有内容再添加
            _fsmStates.Clear();
            foreach (var entry in sourceStates)
            {
                _fsmStates.Add(entry.Key, entry.Value);
            }
            // 或者直接赋值
            // _fsmStates = new Dictionary<Type, EmptyState>(sourceStates);
        }
    }
    
  • 避免在方法内对目标字典进行未初始化的赋值操作,比如不要直接使用_fsmStates = sourceStates而不先确保_fsmStates不是null(不过字典是引用类型,直接赋值本身没问题,但如果后续有清空操作需注意)。

5. 检查Unity对象生命周期顺序

确保AmalgamFSM组件已挂载到同一GameObject上,且FSMLogic = GetComponent<AmalgamFSM>()没有返回null(可以添加Debug.Log(FSMLogic)验证)。如果AmalgamFSM的Awake方法中有清空状态字典的逻辑,会覆盖Start中传入的内容,需调整生命周期逻辑。


内容的提问来源于stack exchange,提问作者unitedinc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:22:42