如何通过光线投射(Ray Casting)与Vuforia地平面放置的3D对象交互
Vuforia地平面模式下3D对象点击无响应问题解决方案
以下是你遇到问题的核心原因及对应修复方案:
核心问题原因
- 动态生成的对象无法被提前查找:你在
Start生命周期里执行GameObject.FindWithTag时,3D对象还没通过spawnObject方法实例化到场景中,导致eos数组和snake变量全部为空,就算射线命中对象也无法获取Animator组件。 - 射线被地平面碰撞器拦截:Vuforia地平面的
Ground对象如果挂载了碰撞器,射线会优先命中位置更靠前的地面,不会命中上层的3D模型,这也是你在Image Target场景中测试正常、地平面场景失效的最常见原因。 - 实例化对象名称不匹配:通过
Instantiate生成的对象默认会带上(Clone)后缀,你switch判断的名称和实际生成的对象名称不一致,导致逻辑分支无法命中。 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
相关产品推荐
相关产品推荐

