using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class InteractionManager : MonoBehaviour { public static InteractionManager Instance { get; private set; } private Camera mainCamera; private void Awake() { if (Instance == null) Instance = this; mainCamera = Camera.main; } [Header("Layers")] [SerializeField] private LayerMask clickableLayers; [SerializeField] private LayerMask groundLayers; [SerializeField] private LayerMask interactableLayers; [Header("Interaction")] [SerializeField] private List blockReasons; [SerializeField, ReadOnly] private bool active; [SerializeField, ReadOnly] private Interactable interactable; public static Interactable Interactable => Instance.interactable; public static Player LocalPlayer => GameManager.LocalPlayer; public bool IsBlocked => blockReasons.Count > 0; public bool IsActive => active; public void AddBlockReason(string reason) => AddBlockReason(reason, true); public void AddBlockReason(string reason, bool stopMovement) { if (blockReasons.Contains(reason)) return; blockReasons.Add(reason); if (stopMovement) LocalPlayer.Movement.StopMovement(); } public void RemoveBlockReason(string reason) { StartCoroutine(RemoveBlockReasonDelay(reason)); } private IEnumerator RemoveBlockReasonDelay(string reason) { yield return null; blockReasons.Remove(reason); } private void Update() { if (IsBlocked || !Input.GetMouseButtonDown(0) || EventSystem.current.IsPointerOverGameObject()) return; Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100, clickableLayers)) { if (!hit.collider || hit.collider.gameObject.IsInLayerMask(groundLayers)) { if (active) { Deactivate(); if (!LocalPlayer) return; LocalPlayer.Movement.CancelInteraction(); LocalPlayer.Movement.ActivateAgent(); LocalPlayer.Movement.MoveTo(hit.point); } else { if (!LocalPlayer) return; LocalPlayer.Movement.MoveTo(hit.point); } return; } //if (!active && hit.collider.gameObject.IsInLayerMask(groundLayers)) //{ // LocalPlayer.Movement.MoveTo(hit.point); // return; //} Interactable interactable = hit.collider.GetComponent(); if (interactable && !active) { if (this.interactable != interactable) { if (interactable.IsOccupied) return; Debug.Log("Activate New"); Activate(interactable); interactable.Interact(); } else Debug.Log("Same. Skip"); } } } private void SetActive(bool setActive) { Debug.Log($"Interaction: {setActive}"); active = setActive; } private void Activate(Interactable interactable) { this.interactable = interactable; SetActive(true); LocalPlayer.Movement.StopMovement(); } public void Deactivate() { if (!active) return; LocalPlayer.Movement.OutInteraction(Interactable.GoToPoint.transform.position); interactable.Uninteract(); interactable = null; SetActive(false); } public void InteractionAnim(string anim) { LocalPlayer.Movement.OnInteraction(Interactable.FinishPoint.transform.position, Interactable.Rotation); LocalPlayer.PlayAnimation(anim); } }