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

Unity C# List重复存放枚举状态BasicIdle时切换卡死问题

问题根因

循环bug和枚举值为0没有关系,核心错误出在状态索引的查找逻辑上:
你使用List.FindIndex()匹配当前状态时,该方法永远只会返回列表中第一个符合匹配条件的元素索引,完全没有记录状态遍历的实际进度。

举个实际运行的例子,假设你在Inspector配置的列表顺序为[BasicIdle, PlayingWithKids, BasicIdle, Bored]:

  1. 初始状态在索引0的BasicIdle,等待时长结束后,FindIndex找到第一个BasicIdle的索引为0,+1得到1,切换到PlayingWithKids,运行正常
  2. PlayingWithKids时长结束后,FindIndex找到第一个PlayingWithKids的索引为1,+1得到2,切换到第二个BasicIdle,此时看似运行正常
  3. 第二个BasicIdle时长结束后,FindIndex查找BasicIdle时依然只会返回第一个匹配项的索引0,+1得到1,再次切回PlayingWithKids,之后就会一直在PlayingWithKids和第二个BasicIdle之间循环,永远走不到后面的Bored状态,和你遇到的现象完全一致。
修复方案

不需要修改枚举定义、状态切换方法和各状态的执行逻辑,只要新增一个字段单独记录当前遍历到的列表索引,不要每次靠状态值反查位置即可:

  1. 首先在类的成员变量区域新增索引记录字段:
// 记录当前状态在配置列表中的索引,初始值对应列表第一个元素
private int currentStateIndex = 0;
  1. 替换FixedUpdate中原来的索引查找逻辑,直接对记录的索引做递增即可:
private void FixedUpdate()
{
    if (Time.timeSinceLevelLoad > prevIdleStateChangeTime + currentStateDuration)
    {
        // 直接移动到下一个状态的索引
        currentStateIndex++;
        // 遍历到列表末尾时重置到开头
        if (currentStateIndex >= availableIdleStates.Count)
        {
            currentStateIndex = 0;
        }
        changeState(availableIdleStates[currentStateIndex]);
    }

    // 下方原有的switch状态执行逻辑完全不需要改动
    switch (currentIdleState)
    {
        case IdleState.BasicIdle:
            if (Time.timeSinceLevelLoad > subStateChangeTime + subStateDuration)
            {
                subStateChangeTime = Time.timeSinceLevelLoad;
                switch (randInt)
                {
                  // 原有子状态逻辑保持不变
                }
            }
            break;

        case IdleState.PlayingWithKids:
            if (Time.timeSinceLevelLoad > subStateChangeTime + subStateDuration)
            {
                int randInt = Random.Range(0, 3);
                subStateChangeTime = Time.timeSinceLevelLoad;
                switch (randInt)
                {
                  // 原有子状态逻辑保持不变
                }
            }
            break;

        // 其余状态的逻辑和原有结构一致即可
    }
}

补充说明:如果运行时存在动态增删availableIdleStates列表元素的需求,只要在修改列表后加一行校验,把currentStateIndex钳制到0 ~ availableIdleStates.Count-1的合法区间即可,固定在Inspector配置的列表不需要额外处理。

你原来写的changeState方法逻辑没有问题,不需要做任何修改。改完之后不管你在列表里加多少次BasicIdle,都会按照配置的顺序依次执行,不会再出现卡循环的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:18:21