Build the tracker in your HUD.
Owning-client widgets must read replicated state first. Do not wait for the first event. Do not use bool returns on the client.
The plugin zip does not include a HUD. The sample project includes an example tracker, log, and vendor board.
Get the component
On the local player, get PlayerState, then FindComponentByClass<UQuestComponent>.
Do not use the bool on the owning client to update the HUD. On construct, fill from queries. When the log opens, refresh. Fail and abandon then appear.
void UMyTrackerWidget::NativeConstruct()
{
Super::NativeConstruct();
UQuestComponent* QC = GetOwningQuestComponent();
ActiveQuests = QC->GetQuestsByStatus(EQuestStatus::Active);
RebuildRows();
QC->OnObjectiveProgress.AddDynamic(this, &UMyTrackerWidget::OnProgress);
}
Quest tracker
UQuestComponent* QC = PlayerState->FindComponentByClass<UQuestComponent>();
TArray<FQuestRuntimeState> Active = QC->GetQuestsByStatus(EQuestStatus::Active);
if (Active.Num() == 0)
{
return;
}
const FQuestRuntimeState& State = Active[0];
UQuestDefinition* Def = GetGameInstance()
->GetSubsystem<UQuestSubsystem>()
->GetQuestById(State.QuestId);
Walk Def->Phases[State.CurrentPhaseIndex].Objectives.
Before you add a row, call UQuestComponent::ShouldDisplayObjective.
Bind the same delegates with AddDynamic. Then rebuild the widget.
Quest log
Call the same GetQuestsByStatus values. Build your Slate or UMG list from the returned array.
For a history of completions, use TimesCompleted on the runtime state.
Vendor / NPC board
TArray<FQuestRuntimeState> Offered = QC->GetQuestsByStatusForGiver(
EQuestStatus::Available, GiverId);
TArray<UQuestDefinition*> Defs = Subsystem->GetQuestsByVendorId(VendorId);
Icons and sounds
Load UQuestDefinition::Icon, each objective Icon, and each reward Icon in your HUD.
When a quest completes, fails, or an objective completes, load the matching USoundCue from the definition. Then play it in your game.