83 lines
3.0 KiB
C#
83 lines
3.0 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
// 미션 하나. 자식의 MissionObjective들이 전부 완료되면 미션이 완료된다.
|
|
// 시작은 Activate()를 UnityEvent(대화 노드 이벤트, 이벤트존, 버튼 등)로 호출하거나
|
|
// ActivateOnStart를 켠다. 완료는 StoryState에 영구 기록되므로
|
|
// DialogCondition의 RequiredMissionIds로 대화 활성화 조건에 쓸 수 있다.
|
|
public class Mission : MonoBehaviour
|
|
{
|
|
public enum MissionState { Inactive, Active, Completed }
|
|
|
|
[Tooltip("StoryState에 기록되는 Id. 비워두면 오브젝트 이름 사용 (DialogCondition의 RequiredMissionIds에서 참조)")]
|
|
[SerializeField] private string _id;
|
|
|
|
[Tooltip("씬 시작 시 자동으로 시작. 끄면 Activate()를 대화 노드 이벤트/존/버튼 등에서 호출할 것")]
|
|
[SerializeField] private bool _activateOnStart;
|
|
|
|
[Tooltip("이 미션을 처음 완료하면 메인 진행도 +N")]
|
|
[Min(0)] [SerializeField] private int _progressOnComplete;
|
|
|
|
[Header("Events")]
|
|
public UnityEvent OnActivated; // 미션 시작 시 (안내 대사, 미션 UI 표시 등)
|
|
public UnityEvent OnCompleted; // 미션 완료 시 (보상 대사, VFX, UI 숨김 등)
|
|
|
|
public MissionState State { get; private set; } = MissionState.Inactive;
|
|
public string Id => string.IsNullOrEmpty(_id) ? name : _id;
|
|
|
|
private MissionObjective[] _objectives;
|
|
|
|
private void Awake()
|
|
{
|
|
_objectives = GetComponentsInChildren<MissionObjective>(true);
|
|
foreach (var objective in _objectives)
|
|
objective.Changed += Reevaluate;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// 저장된 상태에 이미 완료로 기록돼 있으면(이어하기 등) 이벤트 없이 완료 상태로 시작
|
|
if (StoryManager.Instance.IsMissionCompleted(Id))
|
|
State = MissionState.Completed;
|
|
else if (_activateOnStart)
|
|
Activate();
|
|
}
|
|
|
|
// UnityEvent 연결용 — 대화의 '수락' 노드 이벤트 등에서 호출
|
|
public void Activate()
|
|
{
|
|
if (State != MissionState.Inactive) return;
|
|
if (StoryManager.Instance.IsMissionCompleted(Id))
|
|
{
|
|
State = MissionState.Completed;
|
|
return;
|
|
}
|
|
|
|
State = MissionState.Active;
|
|
OnActivated?.Invoke();
|
|
Reevaluate(); // 이미 조건이 갖춰져 있을 수도 있다 (물건을 미리 옮겨둔 경우)
|
|
}
|
|
|
|
private void Reevaluate()
|
|
{
|
|
if (State != MissionState.Active) return;
|
|
foreach (var objective in _objectives)
|
|
if (!objective.IsComplete) return;
|
|
Complete();
|
|
}
|
|
|
|
private void Complete()
|
|
{
|
|
State = MissionState.Completed;
|
|
|
|
var story = StoryManager.Instance;
|
|
bool firstTime = story.MarkMissionCompleted(Id);
|
|
if (firstTime && _progressOnComplete > 0)
|
|
story.MainProgress += _progressOnComplete;
|
|
story.Save();
|
|
|
|
OnCompleted?.Invoke();
|
|
Debug.Log($"[Mission] 완료: {Id}");
|
|
}
|
|
}
|