using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.Interaction.Toolkit.AR; using UnityEngine.XR.ARSubsystems; public class InputManager : ARBaseGestureInteractable { private Camera arCam; // Asignable dinámicamente private ARRaycastManager _raycastManager; // Asignable dinámicamente [SerializeField] private GameObject crosshair; private List _hits = new List(); private Touch touch; private Pose pose; // Método para asignar la cámara desde MeasuringSystem public void SetCamera(Camera camera) { arCam = camera; Debug.Log($"Cámara asignada: {arCam.name}"); } // Método para asignar el ARRaycastManager desde MeasuringSystem public void SetARRaycastManager(ARRaycastManager raycastManager) { _raycastManager = raycastManager; Debug.Log($"ARRaycastManager asignado: {_raycastManager.name}"); } protected override bool CanStartManipulationForGesture(TapGesture gesture) { if (gesture.targetObject == null) return true; return false; } protected override void OnEndManipulation(TapGesture gesture) { if (gesture.isCanceled) return; if (gesture.targetObject != null && IsPointerOverUI(gesture)) return; // Validar referencias antes de ejecutar la lógica if (_raycastManager == null) { Debug.LogWarning("ARRaycastManager no asignado. No se puede realizar raycast."); return; } // Clear _hits and use it with the out parameter _hits.Clear(); if (_raycastManager.Raycast(gesture.startPosition, _hits, TrackableType.PlaneWithinPolygon)) { pose = _hits[0].pose; GameObject placeObj = Instantiate(DataHandler.Instance.GetFurniture(), pose.position, pose.rotation); } } void FixedUpdate() { if (arCam == null || _raycastManager == null) { Debug.LogWarning("Cámara o ARRaycastManager no asignados. No se puede calcular crosshair."); return; } CrosshairCalculation(); } bool IsPointerOverUI(TapGesture touch) { PointerEventData eventData = new PointerEventData(EventSystem.current); eventData.position = new Vector2(touch.startPosition.x, touch.startPosition.y); List results = new List(); EventSystem.current.RaycastAll(eventData, results); return results.Count > 0; } void CrosshairCalculation() { Vector3 origin = arCam.ViewportToScreenPoint(new Vector3(0.5f, 0.5f, 0)); // Clear _hits and use it with the out parameter _hits.Clear(); if (_raycastManager.Raycast(origin, _hits, TrackableType.PlaneWithinPolygon)) { pose = _hits[0].pose; crosshair.transform.position = pose.position; crosshair.transform.eulerAngles = new Vector3(90, 0, 0); } } public bool IsPointInsidePolygon(Vector2 point, List polygon) { int j = polygon.Count - 1; bool inside = false; for (int i = 0; i < polygon.Count; j = i++) { if ((polygon[i].y > point.y) != (polygon[j].y > point.y) && (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) { inside = !inside; } } return inside; } }