Dialogue callback arrives after another Objective is active
The expected-ID guard returns false. Do not complete the new row with a stale callback.
Practical Guides
Wait for a dialogue callback or the Chapter external-animation gate, then advance exactly once.
Goal: advance one Ordered Objective only when an external dialogue reports a confirmed ending. Keep the vendor API in a project integration component. The bridge receives the callback, verifies that the Manager has an Active Objective and its ID equals the expected ID, then calls Chapter.TryCompleteObjective.
Variant: if the dialogue controller already exposes a parameterless UnityEvent and no typed result is needed, bind it to a linked base Objective.CompleteFromEvent.
Goal: make Objective start actions wait until an externally controlled animation ends. Enable Wait For External Animation on the Ordered Objective. Start the animation from an earlier Chapter event or project controller, then call Chapter.SignalExternalAnimationCompleted() exactly once from the final Animation Event or state-machine callback.
The signal releases the gate; it does not complete the Objective. After release, start transport, object activation/deactivation, and On Objective Start run. The Chapter consumes the flag. If the Objective is completed while still waiting, its coroutine is stopped and late start work will not execute.
The expected-ID guard returns false. Do not complete the new row with a stale callback.
The Chapter-level flag can be consumed by the next waiting row. Emit it from the animation instance belonging to the current position.
Coalesce them in the vendor bridge so only the definitive result calls progression.
Use MultiActionObjective branches when simultaneous named signals form one condition; use separate Ordered Objectives when they are sequential tasks.
The compiled examples below contain no dependency on a dialogue or animation vendor and use only the public API.
using System;
using System.Collections;
using System.Collections.Generic;
using OverFuture.ChapterObjectiveSystem.Chapters;
using OverFuture.ChapterObjectiveSystem.Events;
using OverFuture.ChapterObjectiveSystem.Objectives;
using OverFuture.ChapterObjectiveSystem.Persistence;
using OverFuture.ChapterObjectiveSystem.Progression;
using UnityEngine;
public sealed class DialogueIntegrationExample : MonoBehaviour
{
public bool NotifyDialogueFinished(string expectedObjectiveId)
{
ChapterManager manager = ChapterManager.Instance;
Chapter chapter = manager != null ? manager.CurrentChapter : null;
return chapter != null && manager.HasActiveObjective &&
string.Equals(
manager.CurrentObjectiveId,
expectedObjectiveId,
StringComparison.Ordinal) &&
chapter.TryCompleteObjective(expectedObjectiveId);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using OverFuture.ChapterObjectiveSystem.Chapters;
using OverFuture.ChapterObjectiveSystem.Events;
using OverFuture.ChapterObjectiveSystem.Objectives;
using OverFuture.ChapterObjectiveSystem.Persistence;
using OverFuture.ChapterObjectiveSystem.Progression;
using UnityEngine;
public sealed class ExternalAnimationGateExample : MonoBehaviour
{
public bool NotifyAnimationFinished()
{
ChapterManager manager = ChapterManager.Instance;
Chapter chapter = manager != null ? manager.CurrentChapter : null;
if (chapter == null || !manager.HasActiveObjective)
{
return false;
}
chapter.SignalExternalAnimationCompleted();
return true;
}
}