Files
Dino_Love_Simulation/Assets/02_Scripts/Controller/NPCController.cs
2026-07-20 18:12:43 +09:00

102 lines
3.5 KiB
C#

using UnityEngine;
public class NPCController : MonoBehaviour
{
private Animator _anim;
[SerializeField] private int _defaultAnimNo;
[Tooltip("애니메이션 이벤트로 켜고 끌 이펙트들 — 이벤트의 Int 파라미터가 이 목록의 인덱스")]
[SerializeField] private GameObject[] _animationEffects;
[Tooltip("애니메이션 이벤트로 재생할 SFX들 — 이벤트의 Int 파라미터가 이 목록의 인덱스")]
[SerializeField] private AudioClip[] _animationSfx;
private static readonly int _speedHash = Animator.StringToHash("Speed");
private Vector3 _lastPosition;
private float _smoothedSpeed;
private void Awake()
{
_anim = GetComponent<Animator>();
}
private void OnEnable()
{
_lastPosition = transform.position;
_smoothedSpeed = 0f;
}
public void SetAnimState(int animNo)
{
_anim.SetFloat("AnimNo", (float)animNo);
}
public void SetDefaultAnimState()
{
SetAnimState(_defaultAnimNo);
}
// 이동 속도를 재서 Animator의 "Speed" 파라미터로 넘긴다 (블렌드 트리용).
// 속도는 위치 변화량으로 직접 잰다 — Rigidbody가 있어도 kinematic + 트랜스폼 직접 이동(타임라인)은
// 물리를 안 거쳐서 linearVelocity가 항상 0이기 때문. 타임라인이 위치를 쓴 뒤인 LateUpdate에서 잰다.
private void LateUpdate()
{
if (Time.deltaTime <= 0f) return;
// 수평 이동 속도 (m/s)
Vector3 delta = transform.position - _lastPosition;
delta.y = 0f;
_lastPosition = transform.position;
// 프레임 편차로 인한 떨림 방지용 스무딩
_smoothedSpeed = Mathf.Lerp(_smoothedSpeed, delta.magnitude / Time.deltaTime, 10f * Time.deltaTime);
_anim.SetFloat(_speedHash, _smoothedSpeed);
}
// 애니메이션 이벤트용 — 등록된 이펙트 활성화 + 재생 (Int 파라미터 = _animationEffects 인덱스)
public void OnAnimationEffect(int effectNo)
{
var effect = GetEffect(effectNo);
if (effect == null) return;
effect.SetActive(true);
// 이미 켜져 있는 상태에서 이벤트가 또 와도 처음부터 다시 재생되도록
var ps = effect.GetComponentInChildren<ParticleSystem>();
if (ps != null) ps.Play(withChildren: true);
}
// 애니메이션 이벤트용 — 등록된 이펙트 비활성화
public void OffAnimationEffect(int effectNo)
{
var effect = GetEffect(effectNo);
if (effect != null) effect.SetActive(false);
}
private GameObject GetEffect(int effectNo)
{
if (_animationEffects == null || effectNo < 0 || effectNo >= _animationEffects.Length
|| _animationEffects[effectNo] == null)
{
Debug.LogWarning($"[NPCController] 등록되지 않은 이펙트 번호: {effectNo} ({name})");
return null;
}
return _animationEffects[effectNo];
}
// 애니메이션 이벤트용 — 등록된 SFX를 재생 (Int 파라미터 = _animationSfx 인덱스)
public void OnAnimationSfx(int sfxNo)
{
if (_animationSfx == null || sfxNo < 0 || sfxNo >= _animationSfx.Length
|| _animationSfx[sfxNo] == null)
{
Debug.LogWarning($"[NPCController] 등록되지 않은 SFX 번호: {sfxNo} ({name})");
return;
}
if (SoundManager.Instance != null)
SoundManager.Instance.PlaySFX(_animationSfx[sfxNo]);
}
}