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

如何通过光线投射(Ray Casting)与Vuforia地平面放置的3D对象交互

Vuforia地平面模式下3D对象点击无响应问题解决方案

以下是你遇到问题的核心原因及对应修复方案:

核心问题原因

  1. 动态生成的对象无法被提前查找:你在Start生命周期里执行GameObject.FindWithTag时,3D对象还没通过spawnObject方法实例化到场景中,导致eos数组和snake变量全部为空,就算射线命中对象也无法获取Animator组件。
  2. 射线被地平面碰撞器拦截:Vuforia地平面的Ground对象如果挂载了碰撞器,射线会优先命中位置更靠前的地面,不会命中上层的3D模型,这也是你在Image Target场景中测试正常、地平面场景失效的最常见原因。
  3. 实例化对象名称不匹配:通过Instantiate生成的对象默认会带上(Clone)后缀,你switch判断的名称和实际生成的对象名称不一致,导致逻辑分支无法命中。
  4. eos数组未初始化长度:你声明了private GameObject[] eos;但没有指定数组长度,Start中的循环不会执行,数组元素永远为空。

修复方案

1. 优化射线检测逻辑(推荐)

直接从射线命中的对象身上获取Animator组件,不需要提前缓存所有对象,适配动态生成的场景,修改animationTriggerManager脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class animationTriggerManager : MonoBehaviour
{
    [SerializeField]
    private Camera ARCamera;
    // 专门给AR 3D对象设置的层级,避免射线命中地面或者其他无关对象
    public LayerMask arObjectLayer;

    void Update()
    {
        if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began)
        {
            Ray ray = ARCamera.ScreenPointToRay(Input.GetTouch(0).position);
            if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, arObjectLayer))
            {
                Debug.Log("射线命中对象:" + hit.transform.name);
                Animator anim = hit.transform.GetComponent<Animator>();
                if(anim == null) return;
                
                // 根据标签触发对应动画
                if(hit.transform.CompareTag("Snake"))
                {
                    anim.SetTrigger("snakeMoving");
                }
                else if(hit.transform.tag.StartsWith("myEolienne"))
                {
                    anim.SetTrigger("Helice_Rotate");
                    Debug.Log("风车旋转动画触发");
                }
            }
        }
    }
}

2. 配套设置调整

  • 给所有需要点击的3D模型父对象单独设置一个层级(比如命名为ARObject),在脚本的arObjectLayer参数中只选中这个层级,避免射线命中地面。
  • 确保3D模型父对象的Mesh Collider处于启用状态,如果网格过于复杂建议换成Box Collider/Capsule Collider提升检测稳定性。
  • 如果要保留之前的名称判断逻辑,实例化对象时手动修改名称去掉Clone后缀,修改sceneManager的spawnObject方法:
public void spawnObject(int i)
{
    GameObject spawnedObj = Instantiate(renderredPrefab[levelChecker(level)], new Vector3(0, 0, 0), Quaternion.identity, ground.transform);
    spawnedObj.name = renderredPrefab[levelChecker(level)].name;
}

内容的提问来源于stack exchange,提问作者Salah-Eddine Afifi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:39:03