Unity预制体双重碰撞问题:两球体碰撞后生成两个正方形而非一个
问题原因
两个球体都挂载了这个circle脚本,当它们碰撞时,两个对象的OnCollisionEnter2D方法会被分别触发——每个球都会执行一次实例化正方形的逻辑,所以最终生成两个正方形;同时原代码只销毁了当前对象,没有销毁碰撞的另一个球体,也不符合“两者消失”的需求。
解决方案
通过一个静态标志位控制,让只有第一个触发碰撞的球体负责生成正方形并销毁两个对象,第二个球体仅销毁自身,避免重复执行实例化逻辑:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class circle : MonoBehaviour { public GameObject square; // 静态标志位,标记是否正在处理碰撞逻辑 private static bool isCollisionHandled = false; Vector3 pos; void OnCollisionEnter2D(Collision2D collision) { // 仅处理同名称球体的碰撞 if(collision.gameObject.name != this.gameObject.name) return; if(!isCollisionHandled) { // 锁定标志位,防止另一个对象重复执行 isCollisionHandled = true; pos = transform.position; // 销毁当前球体和碰撞的球体 Destroy(gameObject); Destroy(collision.gameObject); // 生成正方形 Instantiate(square, pos, Quaternion.identity); // 延迟重置标志位,避免影响后续碰撞 Invoke(nameof(ResetCollisionFlag), 0.1f); } else { // 第二个触发的球体仅销毁自身 Destroy(gameObject); } } private void ResetCollisionFlag() { isCollisionHandled = false; } }
补充说明
- 静态变量
isCollisionHandled是全局共享的,所以两个球体的脚本会共用这个状态,确保只有第一个进入碰撞逻辑的对象执行生成操作。 - 用
Invoke延迟重置标志位,是为了确保本次碰撞的所有逻辑都执行完毕后再解锁,避免出现异常。 - 如果你的球体是通过预制体批量创建的,建议改用**标签(Tag)**代替名称判断(比如给球体设置
Circle标签,然后判断collision.gameObject.CompareTag("Circle")),比名称判断更可靠。
内容的提问来源于stack exchange,提问作者Matteo Bertoglio
相关产品推荐
相关产品推荐

