Files
StoryGame_Unity/Assets/02_Scripts/Story/StoryDatabase.cs
2026-07-30 13:20:13 +09:00

63 lines
2.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
// 스토리 비트 전체 목록 — "누가 어디서 언제 무슨 대화를 하는가"의 단일 원본.
// 캐릭터 슬롯 활성화(HasPlayableBeat)와 DialogPlayer의 대화 후보(GetPlayableBeats)가
// 전부 이 에셋을 조회한다. 게임에 하나만 만들어 LocationManager에 꽂아 쓴다.
[CreateAssetMenu(menuName = "Story/Story Database")]
public class StoryDatabase : ScriptableObject
{
[Tooltip("스토리 비트 목록 — 위에 있을수록 대화 선택 메뉴에서 우선순위가 높다. " +
"진행도 순으로 정렬해 두면 이 목록이 곧 시나리오 진행표가 된다")]
[SerializeField] private List<StoryBeat> _beats = new();
public IReadOnlyList<StoryBeat> Beats => _beats;
// 이 장소·캐릭터의 비트 중 지금 조건을 만족하는 것들 (목록 순서 유지)
public List<StoryBeat> GetPlayableBeats(LocationData location, CharacterData character)
{
var result = new List<StoryBeat>();
foreach (var beat in _beats)
if (IsPlayable(beat, location, character))
result.Add(beat);
return result;
}
// 이 장소에서 이 캐릭터가 걸 수 있는 대화가 하나라도 있는가 (캐릭터 슬롯 활성화 판정)
public bool HasPlayableBeat(LocationData location, CharacterData character)
{
foreach (var beat in _beats)
if (IsPlayable(beat, location, character))
return true;
return false;
}
// 강제 재생(DialogPlayer.PlayGroup)용 — 이 그룹이 등록된 첫 비트 (없으면 null)
public StoryBeat FindBeat(DialogGroup group)
{
if (group == null) return null;
foreach (var beat in _beats)
if (beat.Group == group)
return beat;
return null;
}
// character가 null이면 "장소 비트"(Character를 비워 둔 항목)를 찾는다 —
// 말을 거는 대상 없이 장소 입장 시 자동 재생되는 대화다.
private static bool IsPlayable(StoryBeat beat, LocationData location, CharacterData character)
{
if (beat.Location != location || beat.Character != character || beat.Group == null)
return false;
// 1회성 비트는 완료 이력이 있으면 후보에서 빠진다 (장소 비트가 입장마다 반복되는 것 방지)
if (beat.OnceOnly)
{
var story = StoryManager.Instance;
if (story != null && story.IsDialogCompleted(beat.Group.name))
return false;
}
return beat.Condition == null || beat.Condition.IsMet(character);
}
}