수정사항

This commit is contained in:
2026-08-06 20:49:36 +09:00
parent 6d6d452922
commit 60c1488716
36 changed files with 1451 additions and 76 deletions

View File

@@ -8,21 +8,43 @@ public class CharacterVoiceObject : MonoBehaviour
private static readonly Dictionary<CharacterData, CharacterVoiceObject> _registry = new();
// Enter Play Mode에서 도메인 리로드를 꺼도 이전 세션의 등록이 남지 않게
// (DialogPlayer·HiddenBranchResolver의 static과 같은 이유)
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStatics() => _registry.Clear();
// Character를 비워 두면 Dictionary 널 키로 예외가 나므로 등록하지 않는다.
// (화자 없는 대화는 CharacterVoiceObject 자체를 붙이지 않는 씬 플레이어로 처리한다)
private void OnEnable()
{
if (Character != null) _registry[Character] = this;
else Debug.LogWarning($"[CharacterVoiceObject] Character가 비어 있어 등록하지 않음: {name}");
if (Character == null)
{
Debug.LogWarning($"[CharacterVoiceObject] Character가 비어 있어 등록하지 않음: {name}");
return;
}
// 같은 캐릭터의 오브젝트가 둘 이상 켜져 있으면 나중 것이 등록을 가져간다.
// 조용히 덮으면 "포즈·보이스가 엉뚱한 오브젝트로 간다"는 재현 어려운 버그가 되므로 알린다.
if (_registry.TryGetValue(Character, out var existing) && existing != null && existing != this)
Debug.LogWarning($"[CharacterVoiceObject] {Character.name} 오브젝트가 둘 이상 활성 상태 — " +
$"'{existing.name}' 대신 '{name}'이 등록된다. 한쪽을 꺼 둘 것");
_registry[Character] = this;
}
private void OnDisable()
{
if (Character != null) _registry.Remove(Character);
// 내가 등록돼 있을 때만 지운다.
// 같은 캐릭터의 오브젝트가 둘일 때 무조건 지우면, 먼저 꺼지는 쪽이 살아 있는 다른 쪽의
// 등록까지 날려서 Find가 null을 반환하게 된다 — 포즈도 보이스도 조용히 죽는 상태다.
if (Character != null
&& _registry.TryGetValue(Character, out var registered) && registered == this)
_registry.Remove(Character);
}
// data가 null이면 Dictionary가 예외를 던지므로 먼저 막는다 (화자 없는 대사 경로에서 올 수 있다)
public static CharacterVoiceObject Find(CharacterData data)
=> _registry.TryGetValue(data, out var obj) ? obj : null;
=> data != null && _registry.TryGetValue(data, out var obj) ? obj : null;
public void Play(AudioClip clip) => VoiceSource.PlayOneShot(clip);
}