Raycast控制Panel激活/停用异常,射线移开后停用功能失效
问题根因
- 面板隐藏逻辑全部嵌套在
Physics.Raycast()返回true的分支内:只有射线成功命中碰撞体时才会执行标签判断。当射线移开、没有命中任何物体时,射线检测直接返回false,根本不会进入内部逻辑,自然无法触发面板停用。 - 存在冗余变量问题:类层级已经声明了全局
private RaycastHit hit;,在FixedUpdate内又重复声明同名局部hit变量,会产生变量遮蔽,属于不规范写法;声明的public Ray handRay;字段全程未被使用,也是冗余代码。 - 直接用
==比较tag的写法效率低,且标签名拼写错误时不会主动抛错,会提升后续排查成本。
修复方案
把面板状态设置逻辑移到射线检测分支外层,不管射线是命中非目标碰撞体、还是完全没命中任何物体,都统一设置面板隐藏,仅在命中标签为Head的碰撞体时激活面板。修复后完整代码如下:
public GameObject myPanel; // 射线最大检测距离,可按需调整 private float rayDetectDistance = 10f; void FixedUpdate() { Vector3 rayDir = transform.TransformDirection(Vector3.forward) * rayDetectDistance; Debug.DrawRay(transform.position, rayDir, Color.green); bool hitTarget = false; if (Physics.Raycast(transform.position, rayDir, out RaycastHit hit)) { // 用CompareTag代替直接==比较tag,性能更好,标签不存在时会主动报错 if (hit.collider.CompareTag("Head")) { hitTarget = true; } } // 统一根据命中结果设置面板显隐,覆盖所有射线未命中目标的场景 myPanel.SetActive(hitTarget); }
额外优化提示
如果后续需要缩小检测范围、忽略指定层级的碰撞体,可以给Physics.Raycast传入层掩码参数,过滤不需要检测的物体,降低不必要的性能消耗。
内容的提问来源于stack exchange,提问作者Maria Cotuna
相关产品推荐
相关产品推荐

