Unity中玩家离开Collider时禁用Canvas并销毁对象的实现问题
Unity 2D碰撞触发UI禁用与对象销毁实现方案
核心问题定位
原有代码存在3个逻辑错误:
- 动画对象销毁逻辑错放在
Update()生命周期中,箱子开启后下一帧就会直接销毁animateObject,LeanTween缩放动画没有足够时间播放 OnTriggerExit2D回调仅处理了交互标记和基础UI显隐,缺失Canvas禁用、目标对象销毁的逻辑- 没有做空引用校验,对象销毁后重复调用API会触发空引用报错
修复实现
首先给类补充Canvas引用字段,修正动画播放、触发离开的逻辑,完整代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.InputSystem; public class Crate : MonoBehaviour { public float duration; public GameObject animateObject; public GameObject crateBox; // 关联箱子UI所属的Canvas组件,直接在Inspector拖拽赋值 public Canvas crateCanvas; public Text crateText; public GameObject crateImage; public GameObject crate; public bool playerInRange; private bool crateOpened = false; // 存储LeanTween动画ID,用于对象销毁前取消动画避免报错 private int tweenId; void Update() { // 箱子未开启时才检测交互输入 if (!crateOpened && Keyboard.current.eKey.wasPressedThisFrame && playerInRange) { crateBox.SetActive(true); crateOpened = true; PlayOpenAnimation(); } } private void OnTriggerEnter2D(Collider2D other) { if(other.CompareTag("Player")) { playerInRange = true; crateImage.SetActive(true); // 进入范围时启用Canvas crateCanvas.enabled = true; } } private void OnTriggerExit2D(Collider2D other) { if(other.CompareTag("Player")) { playerInRange = false; // 离开时禁用Canvas crateCanvas.enabled = false; crateBox.SetActive(false); crateImage.SetActive(false); // 取消正在播放的补间动画 LeanTween.cancel(tweenId); // 销毁动画对象,先判空避免重复销毁报错 if (animateObject != null) { Destroy(animateObject); } } } private void PlayOpenAnimation() { // 初始化动画对象缩放为0,保证从0到1的缩放效果正常 animateObject.transform.localScale = Vector3.zero; tweenId = LeanTween.scale(animateObject, new Vector3(1f, 1f, 1f), duration).id; } }
配置注意事项
- 所有公开字段在Unity Inspector面板完成拖拽赋值,尤其是
crateCanvas字段要关联箱子UI对应的Canvas组件 - 确认玩家对象的Tag设置为
Player,Collider2D的Is Trigger选项已勾选,2D碰撞体矩阵配置正确保证触发事件能正常回调 - 如果需要动画播放完成后自动销毁对象,只需要给LeanTween加完成回调即可,示例:
tweenId = LeanTween.scale(animateObject, new Vector3(1f, 1f, 1f), duration) .setOnComplete(() => { if (animateObject != null) Destroy(animateObject); }).id;
内容的提问来源于stack exchange,提问作者DKINGMAN1223
相关产品推荐
相关产品推荐

