chore: Assets 디렉토리 구조 정리 및 네이밍 컨벤션 적용
- Assets/_Game/ 하위로 게임 에셋 통합 - External/ 패키지 벤더별 분류 (Synty, Animations, UI) - 에셋 네이밍 컨벤션 확립 및 적용 (Data_Skill_, Data_SkillEffect_, Prefab_, Anim_, Model_, BT_ 등) - pre-commit hook으로 네이밍 컨벤션 자동 검사 추가 - RESTRUCTURE_CHECKLIST.md 작성 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
126
Assets/_Game/Scripts/Enemy/EnemyAnimationController.cs
Normal file
126
Assets/_Game/Scripts/Enemy/EnemyAnimationController.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using UnityEngine;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace Colosseum.Enemy
|
||||
{
|
||||
/// <summary>
|
||||
/// 적 캐릭터 애니메이션 컨트롤러
|
||||
/// NavMeshAgent 속도에 따라 Idle/Move 애니메이션 제어
|
||||
/// </summary>
|
||||
public class EnemyAnimationController : NetworkBehaviour
|
||||
{
|
||||
[Header("Animation Parameters")]
|
||||
[SerializeField] private string speedParam = "Speed";
|
||||
[SerializeField] private string attackTriggerParam = "Attack";
|
||||
[SerializeField] private string skillTriggerParam = "Skill";
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private float speedSmoothTime = 0.1f;
|
||||
[SerializeField] private float stopThreshold = 0.05f;
|
||||
|
||||
private Animator animator;
|
||||
private UnityEngine.AI.NavMeshAgent navMeshAgent;
|
||||
private EnemyBase enemyBase;
|
||||
private float currentSpeed;
|
||||
private float speedVelocity;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
navMeshAgent = GetComponent<UnityEngine.AI.NavMeshAgent>();
|
||||
enemyBase = GetComponent<EnemyBase>();
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (!IsServer)
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
UpdateAnimationParameters();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 애니메이션 파라미터 업데이트
|
||||
/// </summary>
|
||||
private void UpdateAnimationParameters()
|
||||
{
|
||||
// 사망 상태에서는 애니메이션 파라미터 업데이트 중단
|
||||
if (enemyBase != null && enemyBase.IsDead)
|
||||
return;
|
||||
|
||||
if (animator == null || navMeshAgent == null)
|
||||
return;
|
||||
|
||||
// NavMeshAgent의 속도를 기반으로 타겟 속도 계산
|
||||
float targetSpeed = navMeshAgent.velocity.magnitude;
|
||||
|
||||
// 정지 임계값 처리
|
||||
if (targetSpeed < stopThreshold)
|
||||
targetSpeed = 0f;
|
||||
|
||||
// 부드러운 속도 변화
|
||||
currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedVelocity, speedSmoothTime);
|
||||
|
||||
// 애니메이터 파라미터 설정
|
||||
animator.SetFloat(speedParam, currentSpeed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 공격 애니메이션 트리거 (외부에서 호출)
|
||||
/// </summary>
|
||||
public void PlayAttack()
|
||||
{
|
||||
if (!IsServer || animator == null)
|
||||
return;
|
||||
|
||||
// 사망 상태에서는 공격 애니메이션 재생하지 않음
|
||||
if (enemyBase != null && enemyBase.IsDead)
|
||||
return;
|
||||
|
||||
animator.SetTrigger(attackTriggerParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 스킬 애니메이션 트리거 (외부에서 호출)
|
||||
/// </summary>
|
||||
public void PlaySkill()
|
||||
{
|
||||
if (!IsServer || animator == null)
|
||||
return;
|
||||
|
||||
// 사망 상태에서는 스킬 애니메이션 재생하지 않음
|
||||
if (enemyBase != null && enemyBase.IsDead)
|
||||
return;
|
||||
|
||||
animator.SetTrigger(skillTriggerParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 애니메이션 트리거 재생
|
||||
/// </summary>
|
||||
/// <param name="triggerName">트리거 파라미터 이름</param>
|
||||
public void PlayTrigger(string triggerName)
|
||||
{
|
||||
if (!IsServer || animator == null)
|
||||
return;
|
||||
|
||||
// 사망 상태에서는 일반 애니메이션 재생하지 않음
|
||||
if (enemyBase != null && enemyBase.IsDead)
|
||||
return;
|
||||
|
||||
animator.SetTrigger(triggerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 애니메이션 속도
|
||||
/// </summary>
|
||||
public float CurrentSpeed => currentSpeed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user