Files
StoryGame_Unity/Assets/02_Scripts/_Data/Evidence/EvidenceDatabase.cs
2026-07-31 11:51:50 +09:00

67 lines
2.6 KiB
C#

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<EvidenceData> _items = new();
[Tooltip("인물 정보 — 사건 관계자")]
[SerializeField] private List<EvidenceData> _profiles = new();
public IReadOnlyList<EvidenceData> 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<EvidenceData> 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
}