AR Foundation:如何避免点击屏幕按钮时3D模型移动?
嗨,我来帮你搞定这个问题!你遇到的核心问题是UI按钮点击和平面点击的事件冲突——默认的「Place On Plane」脚本会响应所有屏幕点击,包括UI区域的点击,所以才会出现点按钮时模型乱跑的情况。下面给你两种实用的解决思路,你可以根据需求选:
方案一:区分UI点击与平面点击(最直接的修复)
这个方法不需要改交互逻辑,只给原脚本加一个判断:只有当点击没有落在UI上时,才执行模型移动/放置的逻辑。
Unity的EventSystem可以帮我们判断点击是否命中UI元素,你只需要找到原脚本里处理屏幕点击的代码块(通常是在Update函数里检测Input.GetMouseButtonDown(0)的部分),在执行核心逻辑前加一段判断:
// 先判断是否点击到了UI元素 if (EventSystem.current.IsPointerOverGameObject()) { return; // 如果点击的是UI,直接跳过后续的模型移动逻辑 }
注意适配触摸设备
如果是在手机等触摸设备上运行,需要把判断改成这样,适配触摸输入的fingerId:
if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); if (EventSystem.current.IsPointerOverGameObject(touch.fingerId)) { return; } }
把这段判断加到所有处理平面点击的代码之前,就能彻底避免UI按钮触发模型移动了。
方案二:改为「选中模型后拖动」的交互逻辑
如果想要完全改变交互方式,只允许选中模型并拖动时才移动它,那可以调整脚本逻辑,分成「选中模型」和「拖动模型」两个阶段:
- 首先给你的3D模型添加一个
Collider组件(比如MeshCollider或者BoxCollider),确保模型能被射线检测到,用MeshCollider的话记得勾选Convex。 - 给模型设置一个专属标签(比如「DraggableModel」),方便脚本识别。
- 修改脚本逻辑,示例代码如下:
using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.EventSystems; public class DragOnPlane : MonoBehaviour { [SerializeField] private ARRaycastManager arRaycastManager; private bool isDragging = false; private GameObject selectedModel; private static List<ARRaycastHit> hits = new List<ARRaycastHit>(); void Update() { // 处理点击选中模型的逻辑 if (Input.GetMouseButtonDown(0)) { // 先判断是否点击UI if (EventSystem.current.IsPointerOverGameObject()) return; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { // 判断是否点击到我们标记的可拖动模型 if (hit.collider.CompareTag("DraggableModel")) { isDragging = true; selectedModel = hit.collider.gameObject; } } } // 处理拖动模型的逻辑 if (Input.GetMouseButton(0) && isDragging) { // 用AR Foundation的射线检测获取平面上的点 if (arRaycastManager.Raycast(Input.mousePosition, hits, TrackableType.Planes)) { var targetPose = hits[0].pose; selectedModel.transform.SetPositionAndRotation(targetPose.position, targetPose.rotation); } } // 松开点击时结束拖动 if (Input.GetMouseButtonUp(0)) { isDragging = false; selectedModel = null; } } }
配置提示
- 记得在Inspector面板里给脚本赋值
ARRaycastManager组件(就是你场景里AR Session Origin下的那个)。 - 确认模型的Collider大小合适,能被轻松点击到。
这两种方案都能解决你的问题,方案一适合想保留原放置逻辑但避免UI冲突的情况,方案二更适合需要精细化交互的场景。
内容的提问来源于stack exchange,提问作者raspberry
相关产品推荐
相关产品推荐

