Enemy의 사망 애니메이션 로직
네트워크 상에서의 동작 확인 완료
This commit is contained in:
@@ -80,8 +80,8 @@ AnimatorController:
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
- m_Name: bIsDeath
|
||||
m_Type: 4
|
||||
- m_Name: Die
|
||||
m_Type: 9
|
||||
m_DefaultFloat: 0
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
@@ -242,7 +242,7 @@ AnimatorStateTransition:
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: bIsDeath
|
||||
m_ConditionEvent: Die
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 3895323774234557799}
|
||||
|
||||
@@ -119,9 +119,24 @@ namespace Northbound
|
||||
{
|
||||
TransitionToState(EnemyAIState.Idle);
|
||||
}
|
||||
|
||||
// 사망 이벤트 구독
|
||||
if (_enemyUnit != null)
|
||||
{
|
||||
_enemyUnit.OnDeath += HandleDeath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (_enemyUnit != null)
|
||||
{
|
||||
_enemyUnit.OnDeath -= HandleDeath;
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
@@ -134,6 +149,7 @@ namespace Northbound
|
||||
case EnemyAIState.ChasePlayer: UpdateChasePlayer(); break;
|
||||
case EnemyAIState.Attack: UpdateAttack(); break;
|
||||
case EnemyAIState.ReturnToOrigin: UpdateReturnToOrigin(); break;
|
||||
case EnemyAIState.Dead: break; // 사망 상태에서는 아무것도 하지 않음
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,11 +487,28 @@ namespace Northbound
|
||||
if (state == EnemyAIState.ChasePlayer) _chaseStartPosition = transform.position;
|
||||
if (state == EnemyAIState.ReturnToOrigin) _agent.SetDestination(_originPosition);
|
||||
break;
|
||||
case EnemyAIState.Dead:
|
||||
_agent.isStopped = true;
|
||||
_agent.ResetPath();
|
||||
_agent.enabled = false; // NavMeshAgent 비활성화
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnExitState(EnemyAIState state) { }
|
||||
|
||||
private void HandleDeath(ulong killerId)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
// 사망 상태로 전환
|
||||
TransitionToState(EnemyAIState.Dead);
|
||||
ClearTargetPlayer();
|
||||
|
||||
if (showDebugInfo)
|
||||
Debug.Log($"<color=red>[EnemyAI] {gameObject.name}이(가) 사망했습니다. (killer: {killerId})</color>");
|
||||
}
|
||||
|
||||
private void OnLostTarget()
|
||||
{
|
||||
ClearTargetPlayer();
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Northbound
|
||||
MoveToCore, // 코어로 이동 (몬스터 기본 상태)
|
||||
ChasePlayer, // 플레이어 추적
|
||||
Attack, // 공격
|
||||
ReturnToOrigin // 원래 위치로 복귀 (적대 세력)
|
||||
ReturnToOrigin, // 원래 위치로 복귀 (적대 세력)
|
||||
Dead // 사망 (아무것도 하지 않음)
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,10 @@ using UnityEngine;
|
||||
visibility.updateInterval = 0.2f;
|
||||
}
|
||||
|
||||
enemy.GetComponent<NetworkObject>().SpawnWithOwnership(NetworkManager.Singleton.LocalClientId);
|
||||
var netObj = enemy.GetComponent<NetworkObject>();
|
||||
netObj.Spawn(true);
|
||||
|
||||
Debug.Log($"<color=cyan>[EnemyPortal] {enemy.name} 스폰됨 - OwnerClientId: {netObj.OwnerClientId}, IsServer: {IsServer}</color>");
|
||||
}
|
||||
|
||||
private void IncreaseCost()
|
||||
|
||||
@@ -32,6 +32,11 @@ namespace Northbound
|
||||
NetworkVariableWritePermission.Server
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 사망 시 발생하는 이벤트 (매개변수: killerId)
|
||||
/// </summary>
|
||||
public event System.Action<ulong> OnDeath;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
base.OnNetworkSpawn();
|
||||
@@ -85,11 +90,14 @@ namespace Northbound
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
// 사망 이벤트 발생 (애니메이션 등)
|
||||
OnDeath?.Invoke(attackerId);
|
||||
|
||||
// 파괴 이펙트
|
||||
ShowDestroyEffectClientRpc();
|
||||
|
||||
// 네트워크 오브젝트 파괴
|
||||
Invoke(nameof(DespawnUnit), 0.5f);
|
||||
Invoke(nameof(DespawnUnit), 3.0f);
|
||||
}
|
||||
|
||||
private void DespawnUnit()
|
||||
|
||||
@@ -18,6 +18,9 @@ namespace Northbound
|
||||
[Tooltip("IsMoving bool parameter name in Animator")]
|
||||
public string isMovingParam = "IsMoving";
|
||||
|
||||
[Tooltip("Death trigger parameter name in Animator")]
|
||||
public string dieTriggerParam = "Die";
|
||||
|
||||
[Header("Settings")]
|
||||
[Tooltip("Auto-load animator controller from MonsterData")]
|
||||
public bool autoLoadFromMonsterData = true;
|
||||
@@ -27,6 +30,7 @@ namespace Northbound
|
||||
|
||||
private Animator _animator;
|
||||
private EnemyAIController _aiController;
|
||||
private EnemyUnit _enemyUnit;
|
||||
private NavMeshAgent _agent;
|
||||
|
||||
private NetworkVariable<float> _networkSpeed = new NetworkVariable<float>(
|
||||
@@ -47,9 +51,14 @@ namespace Northbound
|
||||
|
||||
_animator = GetComponent<Animator>();
|
||||
_aiController = GetComponent<EnemyAIController>();
|
||||
_enemyUnit = GetComponent<EnemyUnit>();
|
||||
_agent = GetComponent<NavMeshAgent>();
|
||||
|
||||
_aiController.OnAttackPerformed += HandleAttackPerformed;
|
||||
if (_enemyUnit != null)
|
||||
{
|
||||
_enemyUnit.OnDeath += HandleDeath;
|
||||
}
|
||||
|
||||
if (autoLoadFromMonsterData)
|
||||
{
|
||||
@@ -63,6 +72,10 @@ namespace Northbound
|
||||
{
|
||||
_aiController.OnAttackPerformed -= HandleAttackPerformed;
|
||||
}
|
||||
if (_enemyUnit != null)
|
||||
{
|
||||
_enemyUnit.OnDeath -= HandleDeath;
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
@@ -74,6 +87,14 @@ namespace Northbound
|
||||
Debug.Log($"[MonsterAnimationController] Triggered attack animation for {target.name}", this);
|
||||
}
|
||||
|
||||
private void HandleDeath(ulong killerId)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
TriggerDeathClientRpc();
|
||||
if (debugLogging)
|
||||
Debug.Log($"[MonsterAnimationController] Triggered death animation (killer: {killerId})", this);
|
||||
}
|
||||
|
||||
private void LoadAnimatorController()
|
||||
{
|
||||
var monsterDataComponent = GetComponent<MonsterDataComponent>();
|
||||
@@ -111,6 +132,14 @@ namespace Northbound
|
||||
|
||||
private void UpdateServerSide()
|
||||
{
|
||||
// 사망 상태면 이동 애니메이션 중지
|
||||
if (_aiController != null && _aiController.GetCurrentState() == EnemyAIState.Dead)
|
||||
{
|
||||
_networkSpeed.Value = 0f;
|
||||
_networkIsMoving.Value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_agent == null) return;
|
||||
|
||||
float currentSpeed = _agent.velocity.magnitude;
|
||||
@@ -137,6 +166,15 @@ namespace Northbound
|
||||
}
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
private void TriggerDeathClientRpc()
|
||||
{
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator.SetTrigger(dieTriggerParam);
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetAttackTrigger()
|
||||
{
|
||||
if (_animator != null)
|
||||
|
||||
Reference in New Issue
Block a user