You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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按钮触发模型移动了。

方案二:改为「选中模型后拖动」的交互逻辑

如果想要完全改变交互方式,只允许选中模型并拖动时才移动它,那可以调整脚本逻辑,分成「选中模型」和「拖动模型」两个阶段:

  1. 首先给你的3D模型添加一个Collider组件(比如MeshCollider或者BoxCollider),确保模型能被射线检测到,用MeshCollider的话记得勾选Convex。
  2. 给模型设置一个专属标签(比如「DraggableModel」),方便脚本识别。
  3. 修改脚本逻辑,示例代码如下:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:07:58