액션 및 인터랙션 시 장비를 착용할 수 있도록 함. 코드 개선 추가
This commit is contained in:
@@ -4,7 +4,7 @@ using UnityEngine;
|
||||
namespace Northbound
|
||||
{
|
||||
/// <summary>
|
||||
/// 액션 - 공격 (팀 시스템 적용)
|
||||
/// 액션 - 공격 (팀 시스템 + 장비 시스템 적용)
|
||||
/// </summary>
|
||||
public class AttackAction : NetworkBehaviour, IAction
|
||||
{
|
||||
@@ -16,6 +16,12 @@ namespace Northbound
|
||||
|
||||
[Header("Animation")]
|
||||
public string attackAnimationTrigger = "Attack";
|
||||
public bool useAnimationEvents = true;
|
||||
public bool blockDuringAnimation = true;
|
||||
|
||||
[Header("Equipment")]
|
||||
public bool useEquipment = true;
|
||||
public EquipmentData equipmentData;
|
||||
|
||||
[Header("Visual")]
|
||||
public GameObject attackEffectPrefab;
|
||||
@@ -24,15 +30,22 @@ namespace Northbound
|
||||
private float _lastAttackTime;
|
||||
private Animator _animator;
|
||||
private ITeamMember _teamMember;
|
||||
private EquipmentSocket _equipmentSocket;
|
||||
private bool _isAttacking = false;
|
||||
private bool _isWeaponEquipped = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_animator = GetComponent<Animator>();
|
||||
_teamMember = GetComponent<ITeamMember>();
|
||||
_equipmentSocket = GetComponent<EquipmentSocket>();
|
||||
}
|
||||
|
||||
public bool CanExecute(ulong playerId)
|
||||
{
|
||||
if (blockDuringAnimation && _isAttacking)
|
||||
return false;
|
||||
|
||||
return Time.time - _lastAttackTime >= attackCooldown;
|
||||
}
|
||||
|
||||
@@ -42,27 +55,43 @@ namespace Northbound
|
||||
return;
|
||||
|
||||
_lastAttackTime = Time.time;
|
||||
_isAttacking = true;
|
||||
|
||||
// 장비 장착 (애니메이션 이벤트 사용 안 할 경우)
|
||||
if (!useAnimationEvents && useEquipment && !_isWeaponEquipped)
|
||||
{
|
||||
if (equipmentData != null && equipmentData.attachOnStart)
|
||||
{
|
||||
AttachWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
// 애니메이션 재생
|
||||
PlayAttackAnimation();
|
||||
|
||||
// 범위 내 적 검색
|
||||
// 애니메이션이 없으면 즉시 공격 실행
|
||||
if (_animator == null || string.IsNullOrEmpty(attackAnimationTrigger))
|
||||
{
|
||||
PerformAttack();
|
||||
_isAttacking = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformAttack()
|
||||
{
|
||||
Vector3 attackOrigin = attackPoint != null ? attackPoint.position : transform.position;
|
||||
Collider[] hits = Physics.OverlapSphere(attackOrigin, attackRange, attackableLayer);
|
||||
|
||||
foreach (Collider hit in hits)
|
||||
{
|
||||
// 자기 자신은 제외
|
||||
if (hit.transform.root == transform.root)
|
||||
continue;
|
||||
|
||||
// 대상 확인
|
||||
var targetDamageable = hit.GetComponent<IDamageable>();
|
||||
var targetTeamMember = hit.GetComponent<ITeamMember>();
|
||||
|
||||
if (targetDamageable != null)
|
||||
{
|
||||
// 팀 확인 - 적대 관계인 경우에만 공격
|
||||
if (_teamMember != null && targetTeamMember != null)
|
||||
{
|
||||
if (!TeamManager.CanAttack(_teamMember, targetTeamMember))
|
||||
@@ -92,13 +121,11 @@ namespace Northbound
|
||||
|
||||
private void PlayAttackAnimation()
|
||||
{
|
||||
// 애니메이션 트리거
|
||||
if (_animator != null && !string.IsNullOrEmpty(attackAnimationTrigger))
|
||||
{
|
||||
_animator.SetTrigger(attackAnimationTrigger);
|
||||
}
|
||||
|
||||
// 이펙트 생성
|
||||
if (attackEffectPrefab != null && attackPoint != null)
|
||||
{
|
||||
GameObject effect = Instantiate(attackEffectPrefab, attackPoint.position, attackPoint.rotation);
|
||||
@@ -106,6 +133,108 @@ namespace Northbound
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Animation Event 함수들
|
||||
// ========================================
|
||||
|
||||
public void OnEquipWeapon()
|
||||
{
|
||||
if (!useAnimationEvents || !useEquipment) return;
|
||||
AttachWeapon();
|
||||
}
|
||||
|
||||
public void OnEquipWeapon(string socketName)
|
||||
{
|
||||
if (!useAnimationEvents || !useEquipment) return;
|
||||
AttachWeapon(socketName);
|
||||
}
|
||||
|
||||
public void OnUnequipWeapon()
|
||||
{
|
||||
if (!useAnimationEvents || !useEquipment) return;
|
||||
DetachWeapon();
|
||||
}
|
||||
|
||||
public void OnUnequipWeapon(string socketName)
|
||||
{
|
||||
if (!useAnimationEvents || !useEquipment) return;
|
||||
DetachWeapon(socketName);
|
||||
}
|
||||
|
||||
public void OnAttackHit()
|
||||
{
|
||||
PerformAttack();
|
||||
}
|
||||
|
||||
public void OnAttackComplete()
|
||||
{
|
||||
_isAttacking = false;
|
||||
|
||||
if (useEquipment && equipmentData != null && equipmentData.detachOnEnd && !equipmentData.keepEquipped)
|
||||
{
|
||||
DetachWeapon();
|
||||
}
|
||||
|
||||
Debug.Log("[AttackAction] 공격 완료");
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// 장비 관리 함수들
|
||||
// ========================================
|
||||
|
||||
private void AttachWeapon(string socketName = null)
|
||||
{
|
||||
if (_equipmentSocket == null || equipmentData == null)
|
||||
{
|
||||
Debug.LogWarning("[AttackAction] EquipmentSocket 또는 EquipmentData가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (equipmentData.equipmentPrefab == null)
|
||||
{
|
||||
Debug.LogWarning("[AttackAction] 무기 프리팹이 설정되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
string socket = socketName ?? equipmentData.socketName;
|
||||
_equipmentSocket.AttachToSocket(socket, equipmentData.equipmentPrefab);
|
||||
_isWeaponEquipped = true;
|
||||
|
||||
Debug.Log($"[AttackAction] 무기 장착: {socket}");
|
||||
}
|
||||
|
||||
private void DetachWeapon(string socketName = null)
|
||||
{
|
||||
if (_equipmentSocket == null)
|
||||
return;
|
||||
|
||||
string socket = socketName ?? equipmentData?.socketName;
|
||||
|
||||
if (!string.IsNullOrEmpty(socket))
|
||||
{
|
||||
_equipmentSocket.DetachFromSocket(socket);
|
||||
_isWeaponEquipped = false;
|
||||
|
||||
Debug.Log($"[AttackAction] 무기 해제: {socket}");
|
||||
}
|
||||
}
|
||||
|
||||
public void EquipWeapon()
|
||||
{
|
||||
if (!_isWeaponEquipped && useEquipment)
|
||||
{
|
||||
AttachWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
public void UnequipWeapon()
|
||||
{
|
||||
if (_isWeaponEquipped)
|
||||
{
|
||||
DetachWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetActionName()
|
||||
{
|
||||
return "Attack";
|
||||
@@ -116,11 +245,29 @@ namespace Northbound
|
||||
return attackAnimationTrigger;
|
||||
}
|
||||
|
||||
public EquipmentData GetEquipmentData()
|
||||
{
|
||||
return equipmentData;
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Vector3 attackOrigin = attackPoint != null ? attackPoint.position : transform.position;
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawWireSphere(attackOrigin, attackRange);
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
// 무기 정리
|
||||
if (_isWeaponEquipped)
|
||||
{
|
||||
DetachWeapon();
|
||||
}
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
public bool IsAttacking => _isAttacking;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user