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);
|
||
}
|
||
}
|
||
}
|