using Unity.Netcode; using UnityEngine; using System.Collections; public class PlayerActionHandler : NetworkBehaviour { private bool _isBusy; public bool IsBusy => _isBusy; private Animator _animator; void Awake() => _animator = GetComponent(); // [통로 1] 인터랙션 실행 (대상 중심) public void PerformInteraction(IInteractable target) { if (_isBusy || target == null) return; // 대상으로부터 정보를 가져옴 var provider = (target as MonoBehaviour).GetComponent(); ActionDescriptor desc = provider?.GetActionDescriptor(); StartCoroutine(InteractionRoutine(desc, target)); } // [통로 2] 액션 실행 (행동 중심) public void PerformAction(PlayerActionData actionData, GameObject target = null) { if (_isBusy || actionData == null) return; StartCoroutine(ActionRoutine(actionData, target)); } private IEnumerator InteractionRoutine(ActionDescriptor desc, IInteractable target) { _isBusy = true; if (desc != null) _animator.SetTrigger(desc.animTrigger); target.Interact(gameObject); // 로직 실행 yield return new WaitForSeconds(desc?.duration ?? 0.1f); _isBusy = false; } private IEnumerator ActionRoutine(PlayerActionData data, GameObject target) { _isBusy = true; // 1. 애니메이션 재생 속도 결정 // (나중에 캐릭터 스탯이나 버프에 따라 이 값을 추가로 계산할 수 있습니다) float finalSpeed = data.baseSpeed; _animator.SetFloat("ActionSpeed", finalSpeed); // 2. 애니메이션 실행 if (!string.IsNullOrEmpty(data.animTrigger)) _animator.SetTrigger(data.animTrigger); // 3. 속도에 맞춰 보정된 타격 지연 시간 계산 // 공식: 실제 대기 시간 = 설정된 지연 시간 / 재생 속도 float adjustedImpactDelay = data.impactDelay / finalSpeed; yield return new WaitForSeconds(adjustedImpactDelay); // 4. 타격 효과 실행 if (target != null) { data.ExecuteEffect(gameObject, target); } // 5. 속도에 맞춰 보정된 나머지 시간 계산 float adjustedTotalDuration = data.duration / finalSpeed; float remainingTime = adjustedTotalDuration - adjustedImpactDelay; if (remainingTime > 0) { yield return new WaitForSeconds(remainingTime); } _isBusy = false; } }