몬스터와 크립에 네트워크 관련 컴포넌트가 없는 문제 수정 포탈/캠프와 몬스터/크립 간의 계층 구조 해제 - 네트워크 오브젝트끼리 계층 구조로 둘 수 없음
149 lines
4.6 KiB
C#
149 lines
4.6 KiB
C#
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
namespace Northbound
|
|
{
|
|
[RequireComponent(typeof(Animator))]
|
|
[RequireComponent(typeof(EnemyAIController))]
|
|
public class MonsterAnimationController : NetworkBehaviour
|
|
{
|
|
[Header("Animation Parameters")]
|
|
[Tooltip("Speed parameter name in Animator")]
|
|
public string speedParam = "Speed";
|
|
|
|
[Tooltip("Attack trigger parameter name in Animator")]
|
|
public string attackTriggerParam = "Attack";
|
|
|
|
[Tooltip("IsMoving bool parameter name in Animator")]
|
|
public string isMovingParam = "IsMoving";
|
|
|
|
[Header("Settings")]
|
|
[Tooltip("Auto-load animator controller from MonsterData")]
|
|
public bool autoLoadFromMonsterData = true;
|
|
|
|
[Tooltip("Debug logging")]
|
|
public bool debugLogging = false;
|
|
|
|
private Animator _animator;
|
|
private EnemyAIController _aiController;
|
|
private NavMeshAgent _agent;
|
|
|
|
private NetworkVariable<float> _networkSpeed = new NetworkVariable<float>(
|
|
0f,
|
|
NetworkVariableReadPermission.Everyone,
|
|
NetworkVariableWritePermission.Owner
|
|
);
|
|
|
|
private NetworkVariable<bool> _networkIsMoving = new NetworkVariable<bool>(
|
|
false,
|
|
NetworkVariableReadPermission.Everyone,
|
|
NetworkVariableWritePermission.Owner
|
|
);
|
|
|
|
public override void OnNetworkSpawn()
|
|
{
|
|
base.OnNetworkSpawn();
|
|
|
|
_animator = GetComponent<Animator>();
|
|
_aiController = GetComponent<EnemyAIController>();
|
|
_agent = GetComponent<NavMeshAgent>();
|
|
|
|
_aiController.OnAttackPerformed += HandleAttackPerformed;
|
|
|
|
if (autoLoadFromMonsterData)
|
|
{
|
|
LoadAnimatorController();
|
|
}
|
|
}
|
|
|
|
public override void OnNetworkDespawn()
|
|
{
|
|
if (_aiController != null)
|
|
{
|
|
_aiController.OnAttackPerformed -= HandleAttackPerformed;
|
|
}
|
|
base.OnNetworkDespawn();
|
|
}
|
|
|
|
private void HandleAttackPerformed(GameObject target)
|
|
{
|
|
if (!IsServer) return;
|
|
TriggerAttackClientRpc();
|
|
if (debugLogging)
|
|
Debug.Log($"[MonsterAnimationController] Triggered attack animation for {target.name}", this);
|
|
}
|
|
|
|
private void LoadAnimatorController()
|
|
{
|
|
var monsterDataComponent = GetComponent<MonsterDataComponent>();
|
|
if (monsterDataComponent != null && monsterDataComponent.monsterData != null)
|
|
{
|
|
string animatorPath = monsterDataComponent.monsterData.animationControllerPath;
|
|
if (!string.IsNullOrEmpty(animatorPath))
|
|
{
|
|
RuntimeAnimatorController controller = Resources.Load<RuntimeAnimatorController>(animatorPath);
|
|
if (controller != null)
|
|
{
|
|
_animator.runtimeAnimatorController = controller;
|
|
if (debugLogging)
|
|
Debug.Log($"[MonsterAnimationController] Loaded animator from {animatorPath}", this);
|
|
}
|
|
else if (debugLogging)
|
|
{
|
|
Debug.LogWarning($"[MonsterAnimationController] Could not load animator from {animatorPath}", this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!IsSpawned) return;
|
|
|
|
if (IsServer && IsOwner)
|
|
{
|
|
UpdateServerSide();
|
|
}
|
|
|
|
UpdateClientSide();
|
|
}
|
|
|
|
private void UpdateServerSide()
|
|
{
|
|
if (_agent == null) return;
|
|
|
|
float currentSpeed = _agent.velocity.magnitude;
|
|
bool isMoving = currentSpeed > 0.1f && _agent.isOnNavMesh && !_agent.isStopped;
|
|
|
|
_networkSpeed.Value = currentSpeed;
|
|
_networkIsMoving.Value = isMoving;
|
|
}
|
|
|
|
private void UpdateClientSide()
|
|
{
|
|
if (_animator == null) return;
|
|
|
|
_animator.SetFloat(speedParam, _networkSpeed.Value);
|
|
_animator.SetBool(isMovingParam, _networkIsMoving.Value);
|
|
}
|
|
|
|
[Rpc(SendTo.ClientsAndHost)]
|
|
private void TriggerAttackClientRpc()
|
|
{
|
|
if (_animator != null)
|
|
{
|
|
_animator.SetTrigger(attackTriggerParam);
|
|
}
|
|
}
|
|
|
|
public void ResetAttackTrigger()
|
|
{
|
|
if (_animator != null)
|
|
{
|
|
_animator.ResetTrigger(attackTriggerParam);
|
|
}
|
|
}
|
|
}
|
|
}
|