Unity中Input.GetMouseButton(0)与RaycastHit2D点击影响多对象问题
问题根因
所有挂载该脚本的对象会在每帧独立执行射线检测,现有逻辑未校验射线命中的碰撞体是否属于当前脚本挂载的对象:只要鼠标按住时射线扫到任意draggableLayers层级下的碰撞体,所有脚本实例都会累计自身的按住时长,满足阈值后直接旋转自身,最终出现所有对象同步旋转的现象。
现存逻辑漏洞
- 射线检测逻辑在每个挂载脚本的对象上独立运行,未做命中对象的归属判断
- 只要射线命中任意符合层级的对象就会触发按住计时,没有和当前对象绑定
- 旋转逻辑直接操作当前脚本挂载对象的Transform,完全未关联射线命中结果
- 未命中当前对象时没有重置计时,容易出现累计时长错乱的问题
修正代码
核心修改点:新增命中对象校验,只有射线命中当前脚本挂载的对象时,才累计按住时长、触发旋转逻辑;未命中当前对象时直接重置计时,避免误触发。
private void Update() { if (Input.GetMouseButton(0)) { Ray ray = loadCam.ScreenPointToRay(Input.mousePosition); RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity, draggableLayers); // 校验射线命中的是否为当前对象,兼容碰撞体挂在子物体的情况 bool hitSelf = hit && hit.collider.attachedRigidbody == rb; if (hitSelf) { holdDownTime += Time.deltaTime; } else { holdDownTime = 0; } if (hitSelf && holdDownTime >= 0.5f) { Quaternion targetRotation = Quaternion.Euler(Vector3.zero); // 刚体旋转优先用MoveRotation,比直接改Transform更适配2D物理系统 rb.MoveRotation(Quaternion.RotateTowards(rb.rotation, targetRotation, Time.deltaTime * 500f)); } } if (Input.GetMouseButtonUp(0)) { holdDownTime = 0; } }
可选优化:如果场景中可交互对象数量较多,可以把射线检测逻辑统一放到单个输入管理脚本中,检测到命中目标后只调用对应对象的旋转接口,避免重复做射线检测消耗性能。
内容的提问来源于stack exchange,提问作者Evan
相关产品推荐
相关产品推荐

