2026-04-24 버그수정 및 대사에 맞춘 캐릭터 동작
This commit is contained in:
@@ -19,6 +19,9 @@ public class DialogNode : ScriptableObject
|
||||
//Voice 없음 → LineDuration 대기
|
||||
|
||||
|
||||
[Header("Behavior")]
|
||||
public bool LookAtPlayer;
|
||||
|
||||
[Header("Flow")]
|
||||
public DialogNode Next; // 선택지 없을 때 자동으로 갈 노드
|
||||
public List<DialogChoice> Choices; // 있으면 플레이어 선택 대기
|
||||
|
||||
@@ -8,6 +8,10 @@ public class DialogPlayer : MonoBehaviour
|
||||
[SerializeField] private List<DialogGroup> _dialogGroups;
|
||||
private Dictionary<string, DialogGroup> _dialogGroupMap;
|
||||
private Animator _animator;
|
||||
private int _initialGestureHash;
|
||||
private int _initialExpressionHash;
|
||||
private bool _hasInitialExpression;
|
||||
private readonly Dictionary<Transform, Quaternion> _originalRotations = new();
|
||||
public bool IsPlaying { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
@@ -17,6 +21,16 @@ private void Awake()
|
||||
_dialogGroupMap[g.DialogGroupName] = g;
|
||||
|
||||
_animator = GetComponentInChildren<Animator>();
|
||||
|
||||
if (_animator != null)
|
||||
{
|
||||
_initialGestureHash = _animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
|
||||
if (_animator.layerCount > 1)
|
||||
{
|
||||
_initialExpressionHash = _animator.GetCurrentAnimatorStateInfo(1).fullPathHash;
|
||||
_hasInitialExpression = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Awaitable Play()
|
||||
@@ -56,11 +70,66 @@ public async Awaitable Play(string groupName)
|
||||
finally
|
||||
{
|
||||
IsPlaying = false;
|
||||
RestoreDefaultAnimations();
|
||||
RestoreRotations();
|
||||
}
|
||||
|
||||
Debug.Log("[DialogPlayer] 대화 종료");
|
||||
}
|
||||
|
||||
private void RestoreDefaultAnimations()
|
||||
{
|
||||
if (_animator == null) return;
|
||||
_animator.CrossFade(_initialGestureHash, 0.3f, 0, normalizedTimeOffset: 0f);
|
||||
if (_hasInitialExpression)
|
||||
_animator.CrossFade(_initialExpressionHash, 0.3f, 1, normalizedTimeOffset: 0f);
|
||||
}
|
||||
|
||||
private async Awaitable RotateTowardPlayer(Transform target)
|
||||
{
|
||||
if (Camera.main == null) return;
|
||||
var playerCam = Camera.main.transform;
|
||||
|
||||
float duration = 0.5f;
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < duration)
|
||||
{
|
||||
Vector3 dir = playerCam.position - target.position;
|
||||
dir.y = 0f;
|
||||
if (dir.sqrMagnitude > 0.0001f)
|
||||
{
|
||||
var targetRot = Quaternion.LookRotation(dir);
|
||||
target.rotation = Quaternion.Slerp(target.rotation, targetRot, 10f * Time.deltaTime);
|
||||
}
|
||||
elapsed += Time.deltaTime;
|
||||
await Awaitable.NextFrameAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreRotations()
|
||||
{
|
||||
foreach (var kvp in _originalRotations)
|
||||
{
|
||||
if (kvp.Key != null)
|
||||
_ = RotateToRotation(kvp.Key, kvp.Value);
|
||||
}
|
||||
_originalRotations.Clear();
|
||||
}
|
||||
|
||||
private async Awaitable RotateToRotation(Transform target, Quaternion targetRotation)
|
||||
{
|
||||
float duration = 0.5f;
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (target == null) return;
|
||||
target.rotation = Quaternion.Slerp(target.rotation, targetRotation, 10f * Time.deltaTime);
|
||||
elapsed += Time.deltaTime;
|
||||
await Awaitable.NextFrameAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Awaitable PlayNode(DialogNode node)
|
||||
{
|
||||
var speakerName = node.Speaker != null ? node.Speaker.Name : "(누구?)";
|
||||
@@ -74,6 +143,17 @@ private async Awaitable PlayNode(DialogNode node)
|
||||
voiceObj.Play(node.Voice.Clip);
|
||||
}
|
||||
|
||||
// 플레이어 향해 회전
|
||||
if (node.LookAtPlayer && node.Speaker != null)
|
||||
{
|
||||
var voiceObj = CharacterVoiceObject.Find(node.Speaker);
|
||||
if (voiceObj != null)
|
||||
{
|
||||
_originalRotations.TryAdd(voiceObj.transform, voiceObj.transform.rotation);
|
||||
_ = RotateTowardPlayer(voiceObj.transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.Gesture != null)
|
||||
_animator.CrossFade(node.Gesture.StateName, node.Gesture.CrossFadeDuration, node.Gesture.AnimationLayer);
|
||||
if (node.Expression != null)
|
||||
|
||||
Reference in New Issue
Block a user