using System; using DDD.Interfaces; using DDD.Players.Tycoons; using DDD.Uis; using Sirenix.OdinInspector; using UnityEngine; namespace DDD.Tycoons { public abstract class InteractionFurniture : MonoBehaviour, IPlayerInteraction { [BoxGroup("컴포넌트")] [field: SerializeField, BoxGroup("컴포넌트")] public Transform CenterTransform { get; private set; } [field: SerializeField, BoxGroup("컴포넌트")] public SpriteRenderer VisualLook { get; private set; } [field: SerializeField, BoxGroup("컴포넌트")] public InteractionCanvas InteractionCanvas { get; private set; } [field: SerializeField, BoxGroup("컴포넌트")] public Material OutlineMaterial { get; private set; } [BoxGroup("변수")] [field: SerializeField, BoxGroup("변수")] public bool EnableInteraction { get; private set; } = true; [field: SerializeField, BoxGroup("변수")] public float InteractionRadius { get; private set; } = 2f; [field: SerializeField, BoxGroup("변수")] public string InteractionMessage { get; set; } [BoxGroup("상호작용")] [field: SerializeField, BoxGroup("상호작용")] public bool EnableHoldingInteraction; [field: SerializeField, BoxGroup("상호작용")] public float PlayerHoldingTime = 1f; [Title("실시간 데이터")] [SerializeField] protected bool IsOpened; protected TycoonPlayer CurrentTycoonPlayer; protected Material OriginalMaterial; protected bool IsQuitting; protected bool IsShowing; protected bool IsPlayerInteracting; protected float HoldingElapsedTime; protected Action HoldingAction; private void OnDrawGizmosSelected() { if (!CenterTransform) return; Gizmos.color = Color.blue; Gizmos.DrawWireSphere(CenterTransform.position, InteractionRadius); } protected virtual void Awake() { InitializeComponents(); if (VisualLook) { OriginalMaterial = VisualLook.material; } } protected virtual void OnEnable() { EventManager.OnTycoonGameStarted += OpenTycoonSwitch; EventManager.OnTycoonGameOvered += ClosedTycoonSwitch; RegisterPlayerInteraction(); } protected virtual void Start() { } protected void FixedUpdate() { if (!EnableHoldingInteraction) return; if (IsShowing) { EventManager.InvokeHoldInteracting(HoldingElapsedTime); } if (HoldingElapsedTime > PlayerHoldingTime) { HoldingElapsedTime -= PlayerHoldingTime; HoldingAction?.Invoke(); } float playerHoldingDeltaTime = Time.deltaTime / PlayerHoldingTime; if (IsPlayerInteracting) { HoldingElapsedTime += playerHoldingDeltaTime; } else { if (HoldingElapsedTime > 0f) { HoldingElapsedTime -= playerHoldingDeltaTime; } } } protected virtual void OnDisable() { if (IsQuitting) return; EventManager.OnTycoonGameStarted -= OpenTycoonSwitch; EventManager.OnTycoonGameOvered -= ClosedTycoonSwitch; UnregisterPlayerInteraction(); } protected virtual void OnDestroy() { } private void OnApplicationQuit() { IsQuitting = true; } [Button("컴포넌트 초기화")] protected virtual void InitializeComponents() { if (!CenterTransform) { CenterTransform = transform; } VisualLook = transform.Find("VisualLook").GetComponent(); InteractionCanvas = transform.Find("InteractionCanvas").GetComponent(); CurrentTycoonPlayer = GameManager.Instance.CurrentTycoonPlayer; } public virtual void Interaction() { IsPlayerInteracting = true; } public virtual void CancelInteraction() { IsPlayerInteracting = false; } public virtual bool CanInteraction() => true; public virtual void ShowInteractionUi() { if (OutlineMaterial) { VisualLook.material = OutlineMaterial; } EventManager.InvokeShowInteractionUi(InteractionMessage); EventManager.InvokeHoldInteracting(HoldingElapsedTime); IsShowing = true; } public virtual void HideInteractionUi() { if (OutlineMaterial && VisualLook) { VisualLook.material = OriginalMaterial; } EventManager.InvokeHideInteractionUi(); IsShowing = false; } protected void RegisterPlayerInteraction() { if (EnableInteraction) { GameManager.Instance.CurrentTycoonPlayer.TycoonInput.RegisterPlayerInteraction(this); } } protected void UnregisterPlayerInteraction() { if (EnableInteraction) { GameManager.Instance.CurrentTycoonPlayer.TycoonInput.UnregisterPlayerInteraction(this); } } protected virtual void OpenTycoonSwitch() { IsOpened = true; } protected virtual void ClosedTycoonSwitch() { IsOpened = false; } } }