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

Unity List能否存储重复元素?AI空闲状态切换死循环排查

核心问题答疑
  • C# List<T> 天然支持重复元素存储:枚举属于值类型,同值的枚举项重复存入列表完全符合语法规则,不会抛出任何异常,也不存在存储层面的限制。
  • 不需要补充完整列表控制脚本:当前给出的代码片段已经可以100%定位死循环根因,问题和未贴出的其余状态分支逻辑无关。
死循环根因

原状态切换逻辑使用FindIndex查找当前状态位置,该方法永远返回列表中第一个匹配目标值的元素索引,一旦列表存在重复状态,就会触发索引回跳:

举个实际触发例子:假设配置列表顺序为[BasicIdle, Curious, Bored, Curious, Shy]

  1. 执行到索引3的第二个Curious,计时结束后FindIndex查找Curious只会返回第一个匹配项的索引1,+1后得到索引2,切换到Bored
  2. 索引2的Bored计时结束后,FindIndex查找Bored返回索引2,+1得到索引3,又切回第二个Curious
  3. 两个状态反复跳转,永远无法执行到索引4的Shy,形成无限循环。
修复方案

放弃每次切换时从头查找状态位置的逻辑,新增一个整型变量持久记录当前执行到的列表索引即可,所有原有状态逻辑、changeState方法都不需要改动:

  1. 类中新增索引记录字段:
// 记录当前执行到的状态列表索引,初始值对应列表第一个元素
private int currentStateIndex = 0;
  1. 替换FixedUpdate中原有的索引查找逻辑:
private void FixedUpdate()
{
    if (Time.timeSinceLevelLoad > prevIdleStateChangeTime + currentStateDuration)
    {
        // 直接递增索引,不需要重新查找匹配
        currentStateIndex++;
        if (currentStateIndex >= availableIdleStates.Count)
        {
            currentStateIndex = 0;
            // 此处保留原有列表洗牌的TODO逻辑即可
        }
        changeState(availableIdleStates[currentStateIndex]);
    }

    // 下方原有switch状态分支代码完全不需要修改
    switch (currentIdleState)
    {
        case IdleState.BasicIdle:
            if (Time.timeSinceLevelLoad > subStateChangeTime + subStateDuration)
            {
                subStateDuration = Random.Range(20f, 30f);
                Debug.Log(subStateDuration);
                int randInt = Random.Range(0, 1);
                subStateChangeTime = Time.timeSinceLevelLoad;
                switch (randInt)
                {
                    case 0:
                        CurrentMovingState = Moving.MovingState.MoveAndRotateToTarget;
                        return;
                    case 1:
                        CurrentMovingState = Moving.MovingState.MoveAndRotateToTarget;
                        return;
                }
            }
            return;
        // 其余未贴出的状态分支保持原有写法即可
    }
}
  • 该方案完全兼容Inspector中任意顺序、包含任意重复元素的状态配置,不会再出现索引回跳问题
  • 如果需要运行时动态增删availableIdleStates的元素,只需要在修改列表后校验currentStateIndex小于列表当前长度即可,避免索引越界。

内容的提问来源于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 05:55:05