using UnityEngine; // 게임 씬에 하나. 현재 장소 프리팹을 띄우고, 장소 안 캐릭터 슬롯들의 등장 여부를 갱신한다. // DialogPlayer가 대화 후보를 조회할 때 (Database, Current)를 여기서 가져간다. public class LocationManager : MonoBehaviour { public static LocationManager Instance { get; private set; } [SerializeField] private StoryDatabase _database; [Tooltip("장소 프리팹을 붙일 부모 (비우면 이 오브젝트)")] [SerializeField] private Transform _locationRoot; [Tooltip("게임 시작 시 입장할 장소")] [SerializeField] private LocationData _startLocation; public StoryDatabase Database => _database; public LocationData Current { get; private set; } private GameObject _currentInstance; // 대화 중 진행도/트리거가 바뀌었을 때의 슬롯 갱신 예약. // 대화 도중 화자를 꺼 버리면 재생이 깨지므로, 대화가 끝난 뒤로 미룬다. private bool _refreshPending; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; if (_locationRoot == null) _locationRoot = transform; } private void Start() { if (StoryManager.Instance != null) StoryManager.Instance.Changed += OnStoryChanged; DialogPlayer.AnyActiveChanged += OnDialogActiveChanged; if (_startLocation != null) MoveTo(_startLocation); } private void OnDestroy() { if (Instance != this) return; if (StoryManager.Instance != null) StoryManager.Instance.Changed -= OnStoryChanged; DialogPlayer.AnyActiveChanged -= OnDialogActiveChanged; Instance = null; } // 장소 이동 (이동 버튼의 UnityEvent 연결용). 대화 중에는 무시된다. public void MoveTo(LocationData location) { if (location == null || DialogPlayer.IsAnyActive) return; Current = location; if (_currentInstance != null) Destroy(_currentInstance); _currentInstance = location.Prefab != null ? Instantiate(location.Prefab, _locationRoot) : null; RefreshSlots(); } // 대화로 진행도/트리거가 바뀌면 등장 캐릭터도 달라질 수 있다 private void OnStoryChanged() { if (DialogPlayer.IsAnyActive) { _refreshPending = true; return; } RefreshSlots(); } private void OnDialogActiveChanged(bool active) { if (active || !_refreshPending) return; _refreshPending = false; RefreshSlots(); } private void RefreshSlots() { if (_currentInstance == null || _database == null) return; foreach (var slot in _currentInstance.GetComponentsInChildren(includeInactive: true)) slot.Refresh(_database, Current); } }