如何利用XR Ray Interactor阻止射线穿透GameObject并限制穿墙传送?
解决XR射线穿透房屋导致误传送的问题
核心方案:让射线优先检测房屋并阻断后续逻辑
你的问题本质是XR射线默认会穿透前面对象检测后面的道路,只要把房屋设为射线的「阻挡层」,同时在代码里判断击中对象,就能解决。
1. 图层与射线检测配置
- 把房屋归到
House层,道路归到Road层; - 打开XR Ray Interactor组件,找到Raycast Mask,只勾选
House和Road(别选其他无关层); - 确保房屋的Collider(不管是Mesh/Box/Capsule)不勾选Is Trigger,并且Collider的
Query Trigger Interaction设为Collide——这样射线碰到房屋就会立刻停止,不会穿透到后面的道路。
2. 代码实现:检测击中房屋并阻止传送
给XR Ray Interactor挂个自定义脚本,实时监控射线击中目标,一旦碰到房屋就禁用传送,同时限制射线长度(视觉上不穿墙):
using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; public class BlockHouseTeleport : MonoBehaviour { private XRRayInteractor _rayInteractor; private TeleportationProvider _teleportProvider; private float _originalMaxDistance; void Start() { _rayInteractor = GetComponent<XRRayInteractor>(); _teleportProvider = FindObjectOfType<TeleportationProvider>(); _originalMaxDistance = _rayInteractor.maxRaycastDistance; } void Update() { if (_rayInteractor.TryGetCurrentRaycastHit(out RaycastHit hit)) { var isHitHouse = hit.collider.gameObject.layer == LayerMask.NameToLayer("House"); // 开关传送功能 _teleportProvider.enabled = !isHitHouse; // 调整射线长度,视觉上不穿透房屋 _rayInteractor.maxRaycastDistance = isHitHouse ? hit.distance : _originalMaxDistance; // 可选:修改射线颜色提示不可传送 var rayVisualizer = GetComponent<TeleportationRayVisualizer>(); if (rayVisualizer != null) { rayVisualizer.lineColor = isHitHouse ? Color.red : Color.blue; } } } }
- 脚本会自动记录你原来的射线最大距离,碰到房屋时把射线长度拉到房屋位置,同时关掉传送提供者,射线颜色也会变红提示不可传送。
3. 修复Mesh Collider的问题
你之前加Mesh Collider没生效,大概率是这两个原因:
- 复杂模型的非凸Mesh Collider射线检测不稳定,换成Box/Capsule Collider(贴合房屋形状调整大小),或者勾选Mesh Collider的Convex选项;
- 射线的
Query Trigger Interaction设成了Ignore,导致无视房屋的Collider,改回Collide就行。
4. 快速测试流程
- 确认房屋Collider非Trigger,属于
House层; - 配置XR Ray Interactor的Raycast Mask只包含
House和Road; - 挂上上述脚本,运行场景——射线碰到房屋时会停在表面,传送功能自动禁用,不会穿墙传进房子。
内容的提问来源于stack exchange,提问作者NadCat
相关产品推荐
相关产品推荐

