Unity AR Core中按钮无法触发预制体生成问题求助
问题描述
需要实现两个按钮,点击按钮切换要生成的预制体类型,点击屏幕时在AR平面上生成对应预制体。目前启动后placeablePrefab字段可以通过按钮更新,但按钮点击无响应(已添加控制台日志但无输出),无论是AR Core模板还是3D模板创建的项目都无法正常工作。
问题代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; [RequireComponent(typeof(ARRaycastManager))] public class NewBehaviourScript : MonoBehaviour { private ARRaycastManager raycastManager; private GameObject spawnedObject; private List<GameObject> placedPrefabsList = new List<GameObject>(); [SerializeField] private int maxPrefabSpawnCount; private int placedPrefabCount; public GameObject placeablePrefab; static List<ARRaycastHit> s_Hits = new List<ARRaycastHit>(); private void Awake() { raycastManager = GetComponent<ARRaycastManager>(); } bool TryGetTouchPosition(out Vector2 touchPosition) { if (Input.touchCount > 0) { Debug.Log("Input.touchCount: " + Input.touchCount); if (Input.GetTouch(0).phase == TouchPhase.Began) { Debug.Log("Touch detected at position: " + Input.GetTouch(0).position); touchPosition = Input.GetTouch(0).position; return true; } else { Debug.Log("Touch phase is not Began: " + Input.GetTouch(0).phase); } } touchPosition = default; return false; } private void Update() { if (!TryGetTouchPosition(out Vector2 touchPosition)) { return; } if (raycastManager.Raycast(touchPosition, s_Hits, TrackableType.PlaneWithinPolygon)) { var hitPose = s_Hits[0].pose; if (placedPrefabCount < maxPrefabSpawnCount) { Debug.Log("1"); SpawnPrefab(hitPose); } } } private void SpawnPrefab(Pose hitPose) { spawnedObject = Instantiate(placeablePrefab, hitPose.position, hitPose.rotation); placedPrefabsList.Add(spawnedObject); placedPrefabCount++; } public void SetPrefabType(GameObject prefabType) { placeablePrefab = prefabType; Debug.Log("Prefab updated to: " + prefabType.name); } }
相关截图
排查与解决方案
1. 优先检查按钮事件绑定
- 打开Unity编辑器,选中按钮对象,在Inspector面板的
OnClick()事件列表中:- 确认已拖拽挂载了
NewBehaviourScript的GameObject到对象选择框 - 确认选择了
NewBehaviourScript -> SetPrefabType(GameObject)方法 - 确认已将对应预制体拖拽到方法的参数输入框中
- 确认已拖拽挂载了
- 给
SetPrefabType方法添加日志(如代码中新增的Debug.Log),测试按钮点击是否触发日志输出
2. 修复触摸输入与UI冲突问题
当前代码未区分UI触摸和AR屏幕触摸,导致按钮点击可能被AR触摸逻辑拦截。修改TryGetTouchPosition方法,添加UI判断:
bool TryGetTouchPosition(out Vector2 touchPosition) { if (Input.touchCount > 0) { var touch = Input.GetTouch(0); // 判断触摸是否在UI上,若是则直接返回 if (EventSystem.current.IsPointerOverGameObject(touch.fingerId)) { Debug.Log("Touch is over UI element"); touchPosition = default; return false; } Debug.Log("Input.touchCount: " + Input.touchCount); if (touch.phase == TouchPhase.Began) { Debug.Log("Touch detected at position: " + touch.position); touchPosition = touch.position; return true; } else { Debug.Log("Touch phase is not Began: " + touch.phase); } } touchPosition = default; return false; }
注意:确保场景中存在
EventSystem对象(UI模板默认包含,若没有可右键UI -> Event System创建)
3. 检查AR相关配置(AR Core项目)
- 确认场景中已添加
ARSession和ARSessionOrigin组件 - 确认
ARRaycastManager已正确挂载到ARSessionOrigin对象上 - 确认
maxPrefabSpawnCount在Inspector中设置了大于0的值,否则无法生成预制体 - 测试时确保AR平面已被检测到(屏幕上显示平面网格),否则
raycastManager.Raycast不会返回true
4. 3D模板项目适配
若使用3D模板而非AR Core模板,当前代码依赖AR组件会报错。需移除AR相关代码,修改生成逻辑为基于鼠标/触摸点击3D平面:
// 替换Update方法中的AR射线检测为普通射线检测 private void Update() { if (!TryGetTouchPosition(out Vector2 touchPosition)) { return; } Ray ray = Camera.main.ScreenPointToRay(touchPosition); if (Physics.Raycast(ray, out RaycastHit hit)) { if (placedPrefabCount < maxPrefabSpawnCount) { Debug.Log("Spawning prefab at 3D hit point"); SpawnPrefab(new Pose(hit.point, Quaternion.LookRotation(hit.normal))); } } }
同时确保场景中有可被射线检测的平面(添加Collider组件)
内容的提问来源于stack exchange,提问作者acr1d _
相关产品推荐
相关产品推荐





