Unity实例化预制体克隆无法控制Animator及脚本启用/禁用如何解决?
问题核心原因
- 协程异步逻辑错误:调用
StartCoroutine(Wait())不会阻塞后续代码执行,你写的anim.SetBool("IsFrozen", false)和恢复Enemy脚本的代码会在触发碰撞的瞬间立刻执行,导致冻结状态刚开启就被关闭,自然看不到动画播放和脚本禁用的效果。 - 重复冗余的
GetComponent调用:你已经在Start生命周期里提前获取了anim和script两个组件引用,后续逻辑直接复用变量即可,反复调用GetComponent没有必要,也不是你问题的诱因——只要Animator和Enemy脚本和当前EnemyHealth挂载在同一个GameObject上,Start里的组件获取逻辑是正常生效的。 - 额外可排查点:确认Animator控制器里的布尔参数名完全和代码里的
IsFrozen一致(大小写敏感),且冻结动画的过渡条件配置正确、没有开启不必要的退出时间。
修复方案
把冻结状态恢复的逻辑移到协程内部,等待freezeTime结束后再执行恢复操作,修复后的代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyHealth : MonoBehaviour { public float health; public float freezeTime; public Animator anim; public Enemy script; IEnumerator FreezeCoroutine(){ // 开启冻结状态 anim.SetBool("IsFrozen", true); script.enabled = false; Debug.Log("冻结开始"); // 等待冻结时长结束 yield return new WaitForSeconds(freezeTime); // 恢复状态 anim.SetBool("IsFrozen", false); script.enabled = true; Debug.Log("冻结结束"); } void Start() { // 提前获取组件引用,后续复用即可 anim = GetComponent<Animator>(); script = GetComponent<Enemy>(); } void Update() { if(health <= 0){ Dead(); } } void OnTriggerEnter2D(Collider2D other){ if(other.CompareTag("Harmful")){ Destroy(other.gameObject); TakeDamage(); } if(other.CompareTag("Freezing")){ Destroy(other.gameObject); TakeDamage(); // 启动冻结协程,所有冻结相关逻辑都放在协程内处理 StartCoroutine(FreezeCoroutine()); } } void TakeDamage(){ health -= 1f; } void Dead(){ Destroy(gameObject); } }
可选优化:如果冻结时需要立刻停止敌人移动,可以在开启冻结的逻辑处加一行
GetComponent<Rigidbody2D>().velocity = Vector2.zero清空刚体速度。
内容的提问来源于stack exchange,提问作者Adm1n
相关产品推荐
相关产品推荐

