Unity节奏游戏:按键触发hitcircle_r淡入淡出动画后隐藏问题求助
问题解决:动画播放完成后再隐藏对象
你的代码核心问题是播放动画后立刻调用SetActive(false),这会直接禁用GameObject,导致动画根本来不及播放。下面提供两种可靠的解决方式:
方法1:利用动画事件(推荐,无误差)
在Unity编辑器中给动画剪辑添加事件,让动画播放到最后一帧时自动触发隐藏逻辑,这是最精准的方式。
修改后的代码
public class CursorPress : MonoBehaviour { public bool canBePressed; public KeyCode keyToPress; private GameObject target; void Awake() { // 提前获取目标对象,避免每帧查找浪费性能 target = GameObject.Find("hitcircle_r"); } void Update() { // 合并条件判断,简化逻辑 if (Input.GetKeyDown(keyToPress) && canBePressed && target != null && target.CompareTag("Target")) { // 修复原代码的大小写错误:Play首字母大写 target.GetComponent<Animation>().Play("hitcircle_fading"); // 不再直接隐藏,交给动画事件处理 } } void OnTriggerEnter2D(Collider2D col) { if (col.CompareTag("Target")) { canBePressed = true; } } void OnTriggerExit2D(Collider2D col) { if (col.CompareTag("Target")) { canBePressed = false; } } // 动画事件触发的方法 public void OnAnimationFinish() { target?.SetActive(false); } }
编辑器操作步骤
- 在Project窗口中打开
hitcircle_fading动画剪辑 - 在时间轴的最后一帧位置右键,选择Add Event
- 在Inspector面板的动画事件中,将挂载了
CursorPress脚本的对象拖到Object字段,然后在Function下拉菜单中选择OnAnimationFinish
方法2:使用协程等待动画时长
如果不想操作动画剪辑,可以通过协程等待动画的总时长,再执行隐藏操作。注意:如果动画有速度调整或循环,这种方式可能有误差。
修改后的代码
public class CursorPress : MonoBehaviour { public bool canBePressed; public KeyCode keyToPress; private GameObject target; private Animation targetAnim; void Awake() { target = GameObject.Find("hitcircle_r"); targetAnim = target?.GetComponent<Animation>(); } void Update() { if (Input.GetKeyDown(keyToPress) && canBePressed && target != null && target.CompareTag("Target")) { var animClip = targetAnim?["hitcircle_fading"]; if (animClip != null) { targetAnim.Play("hitcircle_fading"); // 启动协程等待动画时长 StartCoroutine(HideAfterAnimation(animClip.length)); } } } IEnumerator HideAfterAnimation(float delay) { yield return new WaitForSeconds(delay); target?.SetActive(false); } void OnTriggerEnter2D(Collider2D col) { if (col.CompareTag("Target")) { canBePressed = true; } } void OnTriggerExit2D(Collider2D col) { if (col.CompareTag("Target")) { canBePressed = false; } } }
额外优化说明
- 将
GameObject.Find移到Awake中,避免每帧重复查找,提升运行性能 - 使用
CompareTag替代直接比较tag,性能更优且能避免空引用报错 - 修复了原代码中
play的大小写错误(Unity API要求首字母大写的Play)
内容的提问来源于stack exchange,提问作者Smoodie
相关产品推荐
相关产品推荐

