217 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections;
 | ||
| using System.Collections.Generic;
 | ||
| using UnityEngine;
 | ||
| using UnityEngine.XR.ARFoundation;
 | ||
| using UnityEngine.XR.ARSubsystems;
 | ||
| 
 | ||
| public class ObjectSelector : MonoBehaviour
 | ||
| {
 | ||
|     public LayerMask interactableLayer;
 | ||
| 
 | ||
|     private ARRaycastManager arRaycastManager; // Asignable din<69>micamente
 | ||
|     private Camera arCamera; // Asignable din<69>micamente
 | ||
|     private GameObject selectedObject;
 | ||
| 
 | ||
|     private readonly float longTapTreshold = 1f;
 | ||
|     private readonly float doubleTapMaxDelay = 0.5f;
 | ||
|     private float tapTimer = 0f;
 | ||
|     private float lastTapTime = 0f;
 | ||
|     private bool isRelocating = false;
 | ||
|     
 | ||
| 
 | ||
|     // M<>todo para asignar la c<>mara desde MeasuringSystem
 | ||
|     public void SetCamera(Camera camera)
 | ||
|     {
 | ||
|         arCamera = camera;
 | ||
|         Debug.Log($"C<>mara asignada: {arCamera.name}");
 | ||
|     }
 | ||
| 
 | ||
|     // M<>todo para asignar el ARRaycastManager desde MeasuringSystem
 | ||
|     public void SetARRaycastManager(ARRaycastManager raycastManager)
 | ||
|     {
 | ||
|         arRaycastManager = raycastManager;
 | ||
|         Debug.Log($"ARRaycastManager asignado: {arRaycastManager.name}");
 | ||
|         FindObjectOfType<DebugLoggerUI>().AddMessage($"ARRaycastManager asignado: {arRaycastManager.name}");
 | ||
|     }
 | ||
| 
 | ||
|     private void Update()
 | ||
|     {
 | ||
|         if (arCamera == null || arRaycastManager == null)
 | ||
|         {
 | ||
|             Debug.LogWarning("La c<>mara o el ARRaycastManager no han sido asignados.");
 | ||
|             FindObjectOfType<DebugLoggerUI>().AddMessage("La c<>mara o el ARRaycastManager no han sido asignados.");
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         HandleTouchInput();
 | ||
|         HandleRotation();
 | ||
|         UpdateOutline();
 | ||
|     }
 | ||
| 
 | ||
|     private void HandleTouchInput()
 | ||
|     {
 | ||
|         if (Input.touchCount == 1)
 | ||
|         {
 | ||
|             Touch touch = Input.GetTouch(0);
 | ||
| 
 | ||
|             if (touch.phase == TouchPhase.Began)
 | ||
|             {
 | ||
|                 Ray ray = arCamera.ScreenPointToRay(touch.position);
 | ||
|                 if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, interactableLayer))
 | ||
|                 {
 | ||
|                     if (selectedObject == hit.collider.gameObject)
 | ||
|                     {
 | ||
|                         if (Time.time - lastTapTime <= doubleTapMaxDelay)
 | ||
|                         {
 | ||
|                             DeleteObject();
 | ||
|                             lastTapTime = 0f;
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             lastTapTime = Time.time;
 | ||
|                             StartCoroutine(CheckLongTap());
 | ||
|                         }
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         SelectObject(hit.collider.gameObject);
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     DeselectObject();
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             if (touch.phase == TouchPhase.Moved && isRelocating)
 | ||
|             {
 | ||
|                 RelocateObject(touch.position);
 | ||
|             }
 | ||
| 
 | ||
|             if (touch.phase == TouchPhase.Ended)
 | ||
|             {
 | ||
|                 isRelocating = false;
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private IEnumerator CheckLongTap()
 | ||
|     {
 | ||
|         tapTimer = 0f;
 | ||
|         while (tapTimer < longTapTreshold)
 | ||
|         {
 | ||
|             if (Input.touchCount == 0 || Input.GetTouch(0).phase == TouchPhase.Ended)
 | ||
|             {
 | ||
|                 yield break;
 | ||
|             }
 | ||
| 
 | ||
|             tapTimer += Time.deltaTime;
 | ||
|             yield return null;
 | ||
|         }
 | ||
| 
 | ||
|         isRelocating = true;
 | ||
|     }
 | ||
| 
 | ||
|     private void RelocateObject(Vector2 screenPosition)
 | ||
|     {
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             List<ARRaycastHit> hits = new();
 | ||
|             if (arRaycastManager.Raycast(screenPosition, hits, TrackableType.Planes))
 | ||
|             {
 | ||
|                 Pose hitPose = hits[0].pose;
 | ||
| 
 | ||
|                 selectedObject.transform.SetPositionAndRotation(Vector3.Lerp(
 | ||
|                     selectedObject.transform.position,
 | ||
|                     hitPose.position,
 | ||
|                     Time.deltaTime * 10f
 | ||
|                 ), Quaternion.Lerp(
 | ||
|                     selectedObject.transform.rotation,
 | ||
|                     selectedObject.transform.rotation,
 | ||
|                     Time.deltaTime * 10f
 | ||
|                 ));
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void HandleRotation()
 | ||
|     {
 | ||
|         if (selectedObject != null && Input.touchCount == 1)
 | ||
|         {
 | ||
|             Touch touch = Input.GetTouch(0);
 | ||
| 
 | ||
|             if (touch.phase == TouchPhase.Moved)
 | ||
|             {
 | ||
|                 Vector2 touchDelta = touch.deltaPosition;
 | ||
|                 float rotationAmount = touchDelta.x * 0.1f;
 | ||
| 
 | ||
|                 selectedObject.transform.Rotate(0, -rotationAmount, 0, Space.World);
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void SelectObject(GameObject gameObject)
 | ||
|     {
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             DeselectObject();
 | ||
|         }
 | ||
| 
 | ||
|         selectedObject = gameObject;
 | ||
| 
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             EnableOutline(selectedObject);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void DeselectObject()
 | ||
|     {
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             DisableOutline(selectedObject);
 | ||
|         }
 | ||
| 
 | ||
|         selectedObject = null;
 | ||
|     }
 | ||
| 
 | ||
|     private void DeleteObject()
 | ||
|     {
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             Destroy(selectedObject);
 | ||
|             selectedObject = null;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void EnableOutline(GameObject obj)
 | ||
|     {
 | ||
|         if (obj.TryGetComponent<Outline>(out var outline))
 | ||
|         {
 | ||
|             outline.enabled = true;
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|             var newOutline = obj.AddComponent<Outline>();
 | ||
|             newOutline.OutlineColor = Color.cyan;
 | ||
|             newOutline.OutlineWidth = 10f;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void DisableOutline(GameObject obj)
 | ||
|     {
 | ||
|         if (obj.TryGetComponent<Outline>(out var outline))
 | ||
|         {
 | ||
|             outline.enabled = false;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     private void UpdateOutline()
 | ||
|     {
 | ||
|         if (selectedObject != null)
 | ||
|         {
 | ||
|             EnableOutline(selectedObject);
 | ||
|         }
 | ||
|     }
 | ||
| }
 | 
