Unity恐怖游戏开发:可交互物体准星切换代码检查请求
Unity射线检测切换准星问题修正
原代码存在的问题
- 未处理射线未命中可交互物体的场景,此时准星无法切回默认状态
hit.collider.GetComponent<Interactable>() != false判断逻辑错误:GetComponent返回组件实例或null,不能和布尔值比较,应改为判断是否不等于nullhit.collider == null分支完全无效:因为Physics.Raycast返回true时,hit.collider必然不为空,这个分支永远不会执行onInteract未初始化,若交互组件的onInteract为空会引发空引用异常- 准星状态切换的逻辑冗余,容易出现遗漏场景
修正后的代码
using UnityEngine; using UnityEngine.Events; public class ReticleController : MonoBehaviour { public Camera mainCam; public LayerMask interactableLayerMask; [SerializeField] private GameObject reticle; [SerializeField] private GameObject interactReticle; // 缓存当前检测到的交互组件,减少重复GetComponent开销 private Interactable currentInteractable; void Update() { RaycastHit hit; bool isHitInteractable = Physics.Raycast(mainCam.transform.position, mainCam.transform.forward, out hit, 2f, interactableLayerMask); // 先默认重置准星为普通状态,确保未命中时状态正确 reticle.SetActive(true); interactReticle.SetActive(false); currentInteractable = null; if (isHitInteractable) { currentInteractable = hit.collider.GetComponent<Interactable>(); // 确认存在交互组件时切换准星并处理交互逻辑 if (currentInteractable != null) { reticle.SetActive(false); interactReticle.SetActive(true); // 点击检测前先判断事件不为空,避免空引用异常 if (Input.GetKeyDown(KeyCode.Mouse0) && currentInteractable.onInteract != null) { currentInteractable.onInteract.Invoke(); } } } } }
关键改动说明
- 补全未命中逻辑:先默认激活普通准星,再根据命中结果覆盖状态,确保任何场景下准星状态都正确
- 修正组件判断:将错误的布尔值比较改为判断组件是否为
null,符合Unity API的使用逻辑 - 移除无效代码:删除永远不会触发的
hit.collider == null分支 - 增加空引用保护:调用交互事件前先判断事件实例不为空,避免运行时崩溃
- 优化性能与结构:用变量缓存交互组件,减少重复获取组件的开销;调整代码顺序,逻辑更直观
内容的提问来源于stack exchange,提问作者Smoodie
相关产品推荐
相关产品推荐

