Unity中if-else逻辑异常与ANIM_MEDITATION变量取值错误问题咨询
问题原因与修复方案
异常原因
1. ANIM_MEDITATION值异常
Unity的public字段默认会被序列化存储,[HideInInspector]仅会隐藏Inspector面板的显示,不会清除该字段已经保存在场景/预制体中的序列化数据。如果该字段曾经在未加[HideInInspector]时被修改为Strike,或是其他执行顺序更靠前的脚本在当前脚本Awake生命周期之前(如更高优先级脚本的Awake、OnEnable阶段)修改了该字段值,都会覆盖代码中的初始赋值。
另外注意你存在变量名拼写笔误:最初写的定义是ANIM_MEDITATON(缺少字母I),拼写错误的重名变量也可能导致取值异常。
2. if-else分支逻辑异常
你贴出的第一版代码第二个判断看似是写死的字符串"Meditation",但实际项目代码中应该是使用了ANIM_MEDITATION作为判断条件。此时ANIM_MEDITATION的值已经被改为Strike,当遍历到名称为Strike的AnimationClip时,第二个分支clip.name == ANIM_MEDITATION就已命中,会直接走第二个分支的逻辑,自然不会进入后续的Strike判断分支。
你将Strike的判断移到最前面之后,遍历到对应clip时会优先命中第一个分支,所以可以正常进入。
排查修复方法
修复变量值异常
- 方案1:给字段添加
[NonSerialized]属性,强制不使用Unity序列化存储的值,完全以代码初始赋值为准:
[HideInInspector, NonSerialized] public string ANIM_MEDITATION = "Meditation";
- 方案2:直接将字段改为
const或readonly,从语法层面禁止值被修改,更适合这种常量定义场景:
public const string ANIM_MEDITATION = "Meditation";
- 额外检查:确认所有脚本的执行顺序,没有其他脚本在当前脚本
Awake之前修改该字段的值,同时修正所有变量名的拼写错误。
优化分支逻辑避免同类问题
建议放弃串行if-else的判断方式,改用字典映射实现,既不会出现判断顺序问题,遍历性能也更高:
private Dictionary<string, Action<float>> clipHandler; private void Awake() { clipHandler = new Dictionary<string, Action<float>>() { {"Ledge Climb", val => animLedgeClimbTime = val}, {ANIM_MEDITATION, val => animMeditationTime = val}, {"Strike", val => animStrikeTime = val}, {"Strike 2", val => animStrike2Time = val} }; } public void UpdateAnimationTimes() { AnimationClip[] clips = animator.runtimeAnimatorController.animationClips; foreach (AnimationClip clip in clips) { if (clipHandler.TryGetValue(clip.name, out var handler)) { handler(clip.length); } } }
内容的提问来源于stack exchange,提问作者Ata Öz
相关产品推荐
相关产品推荐

