Files
ProjectMD/Assets/Scripts/Player/PlayerActionHandler.cs

79 lines
2.5 KiB
C#

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<Animator>();
// [통로 1] 인터랙션 실행 (대상 중심)
public void PerformInteraction(IInteractable target)
{
if (_isBusy || target == null) return;
// 대상으로부터 정보를 가져옴
var provider = (target as MonoBehaviour).GetComponent<IActionProvider>();
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;
}
}