Unity C#开发抓钩功能时无法销毁Instantiate实例化对象
问题根因
你代码里Destroy(target)无法删除生成的锚点,核心问题是变量引用搞错了:
- 你在Inspector中赋值给
public Transform target的是锚点的预制体原始资源,不是运行时生成在场景里的实例 - 调用
Instantiate()生成锚点时,你没有接收该方法返回的实例引用,后续执行销毁逻辑时,本质是在尝试销毁原始预制体资产,根本碰不到场景里实际生成的那个锚点对象。
修复方案
- 新增私有变量存储运行时生成的锚点实例
在类的字段定义区加一行:private Transform spawnedAnchor; - 实例化锚点时保存实例引用
将原来的Instantiate(target, mousePos, Quaternion.identity);替换为:spawnedAnchor = Instantiate(target, mousePos, Quaternion.identity); - 松开按键时销毁正确的实例对象
将鼠标抬起逻辑块里的Destroy(target);替换为以下代码,销毁前加判空避免空引用报错,销毁后清空引用:if (spawnedAnchor != null) { Destroy(spawnedAnchor.gameObject); spawnedAnchor = null; }
修复后完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class grapple : MonoBehaviour { public Camera mainCamera; public LineRenderer _lineRenderer; public DistanceJoint2D _distanceJoint; public Transform target; // 存储运行时生成的锚点实例 private Transform spawnedAnchor; // Start is called before the first frame update void Start() { _distanceJoint.enabled = false; } // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(1)) { Vector2 mousePos = (Vector2)mainCamera.ScreenToWorldPoint(Input.mousePosition); _lineRenderer.SetPosition(0, mousePos); _lineRenderer.SetPosition(1, transform.position); _distanceJoint.connectedAnchor = mousePos; _distanceJoint.enabled = true; _lineRenderer.enabled = true; // 保存生成的锚点实例引用 spawnedAnchor = Instantiate(target, mousePos, Quaternion.identity); } else if (Input.GetMouseButtonUp(1)) { _distanceJoint.enabled = false; _lineRenderer.enabled = false; // 销毁实际生成的锚点实例 if (spawnedAnchor != null) { Destroy(spawnedAnchor.gameObject); spawnedAnchor = null; } } if (_distanceJoint.enabled) { _lineRenderer.SetPosition(1, transform.position); } } }
补充提示:如果后续要支持连续快速发射抓钩,建议在鼠标按下生成新锚点前,先检查
spawnedAnchor是否有残留值,存在则先销毁旧锚点再生成新的,避免场景中堆积冗余的锚点对象。
内容的提问来源于stack exchange,提问作者RaptoRR
相关产品推荐
相关产品推荐

