using System.Collections.Generic;
using System.Linq;
using Convai.Scripts.Runtime.Features;
using Convai.Scripts.Runtime.LoggerSystem;
using UnityEngine;
namespace Convai.Scripts.Runtime.UI
{
///
/// Handles the crosshair behavior for the Convai application.
/// It can detect which Convai game object the player's crosshair is currently looking at.
///
[DisallowMultipleComponent]
[AddComponentMenu("Convai/Crosshair Handler")]
public class ConvaiCrosshairHandler : MonoBehaviour
{
private Camera _camera;
private Dictionary _interactableReferences;
private ConvaiInteractablesData _interactablesData;
private void Awake()
{
_camera = Camera.main;
_interactablesData = FindObjectOfType();
if (_interactablesData == null) return;
// Build the interactable references dictionary
_interactableReferences = new Dictionary();
foreach (ConvaiInteractablesData.Object eachObject in _interactablesData.Objects)
_interactableReferences[eachObject.gameObject] = eachObject.Name;
foreach (ConvaiInteractablesData.Character eachCharacter in _interactablesData.Characters)
_interactableReferences[eachCharacter.gameObject] = eachCharacter.Name;
}
///
/// Finds the reference object that the player's crosshair is currently looking at.
///
/// A reference string of the interactable object or character, "None" if no valid hit.
public string FindPlayerReferenceObject()
{
if (_interactablesData == null || _camera == null) return "None";
Vector3 centerOfScreen = new(0.5f, 0.5f, 0);
if (Physics.Raycast(_camera.ViewportPointToRay(centerOfScreen), out RaycastHit hit))
{
_interactablesData.DynamicMoveTargetIndicator.position = hit.point;
string reference = FindInteractableReference(hit.transform.gameObject);
ConvaiLogger.DebugLog($"Player is looking at: {reference}", ConvaiLogger.LogCategory.Actions);
return reference;
}
return "None";
}
///
/// Finds the reference object that the player's crosshair is currently looking at.
///
/// The game object that the player's crosshair is currently looking at.
/// A reference string(name) of the interactable object or character, "None" if no valid hit.
private string FindInteractableReference(GameObject hitGameObject)
{
foreach (KeyValuePair kvp in _interactableReferences.Where(kvp => hitGameObject.GetComponentInParent() == kvp.Key.transform))
return kvp.Value;
return "None";
}
}
}