using System.Collections.Generic; using UnityEngine; // 증거품의 하위 분류. 어느 목록에 들어 있는지가 곧 분류다 (EvidenceDatabase 참고). public enum EvidenceCategory { [InspectorName("소지품")] Item, [InspectorName("인물 정보")] Profile, } // 게임에 존재하는 모든 증거품 항목의 목록 (StoryDatabase와 같은 "단일 원본" 역할). // // 분류마다 목록을 따로 둔다. 데이터를 넣는 사람은 드롭다운을 고를 필요 없이 // 해당 목록에 끌어다 놓기만 하면 되고, 분류가 두 곳에 적히지 않으니 어긋날 수도 없다. // // 저장 파일에는 Id 문자열만 남으므로, Id → EvidenceData 복원은 이 에셋이 담당한다. // 게임에 하나만 만들어 EvidenceHud에 꽂아 쓴다. [CreateAssetMenu(menuName = "Evidence/Evidence Database")] public class EvidenceDatabase : ScriptableObject { [Tooltip("소지품 — 물건 증거품")] [SerializeField] private List _items = new(); [Tooltip("인물 정보 — 사건 관계자")] [SerializeField] private List _profiles = new(); public IReadOnlyList GetEntries(EvidenceCategory category) => category == EvidenceCategory.Item ? _items : _profiles; // Id로 항목을 찾고 그 분류까지 함께 알려준다. 어느 목록에도 없으면 null. public EvidenceData FindById(string id, out EvidenceCategory category) { category = EvidenceCategory.Item; if (string.IsNullOrEmpty(id)) return null; var found = FindIn(_items, id); if (found != null) return found; category = EvidenceCategory.Profile; return FindIn(_profiles, id); } public EvidenceData FindById(string id) => FindById(id, out _); private static EvidenceData FindIn(List list, string id) { foreach (var entry in list) { if (entry == null) continue; string entryId = string.IsNullOrEmpty(entry.Id) ? entry.name : entry.Id; if (entryId == id) return entry; } return null; } #if UNITY_EDITOR // 같은 항목을 두 목록에 넣으면 분류가 모호해지므로(먼저 찾은 쪽이 이긴다) 넣는 즉시 알려준다. private void OnValidate() { foreach (var entry in _items) if (entry != null && _profiles.Contains(entry)) Debug.LogWarning($"[EvidenceDatabase] '{entry.name}'이(가) 소지품과 인물 정보 " + "양쪽에 있습니다 — 한쪽에서 빼주세요", this); } #endif }