MVVM & UI

Table of Contents

  1. Overview
  2. ViewModel Hierarchy
  3. UMVVMPulseQuestManager
    1. Lazy creation
  4. UMVVMPulseQuest
  5. UMVVMPulseObjective

Overview

PulseQuest provides a set of pre-wired MVVM ViewModels (built on Unreal’s UMVVMViewModelBase) for every layer of the quest hierarchy. You bind these to UMG widgets using the standard MVVM binding system.

ViewModels are created lazily on first access, not during BeginPlay. This avoids overhead when quests/objectives are running headlessly on the server or during automated tests.


ViewModel Hierarchy

UMVVMPulseQuestManager          ← one per quest manager
  └── UMVVMPulseQuest           ← one per active quest
       └── UMVVMPulseObjective  ← one per active objective

UMVVMPulseQuestManagerData      ← wraps UPulseQuestManagerData

UMVVMPulseQuestManager

Attached to UPulseQuestManager or APulseSharedQuestHost. Provides:

Field Type Notify
ActiveQuests TArray<UMVVMPulseQuest*> FieldNotify
ActiveObjectives TArray<UMVVMPulseObjective*> FieldNotify
ManagerData UMVVMPulseQuestManagerData* FieldNotify

Lazy creation

// Called on first access
UMVVMPulseQuestManager* GetQuestManagerViewModel() const;

If no QuestManagerViewModelClass is set in ManagerParams, no ViewModel is created and the getter returns nullptr.


UMVVMPulseQuest

One per active quest; created when the quest starts.

Field Type Notify
QuestTag FGameplayTag FieldNotify
DisplayName FText FieldNotify
Description FText FieldNotify
FinishState EPulseQuestFinishResult FieldNotify
ActiveObjectives TArray<UMVVMPulseObjective*> FieldNotify
bIsStopped bool FieldNotify

Access:

UMVVMPulseQuest* VM = QuestData->GetQuestDataViewModel();

UMVVMPulseObjective

One per active objective (when ViewModelClass is set on the objective).

Field Type Notify
SaveID FName FieldNotify
FinishStatus EPulseObjectiveCompletionStatus FieldNotify
bIsFinished bool FieldNotify
Progress float (0–1) FieldNotify

Access:

UMVVMPulseObjective* VM = Objective->GetObjectiveViewModel();

Subclass UMVVMPulseObjective to add your own fields (e.g. CurrentCount, TargetCount):

UCLASS()
class UMVVMMyKillObjective : public UMVVMPulseObjective
{
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite, FieldNotify)
    int32 KillCount = 0;

    UPROPERTY(BlueprintReadWrite, FieldNotify)
    int32 KillTarget = 10;
};

Then set ViewModelClass = UMVVMMyKillObjective::StaticClass() in the objective’s FPulseQuestObjectiveAddParams.



Back to top

Copyright © 2026 LuQ Studios. Distributed under the MIT License.

This site uses Just the Docs, a documentation theme for Jekyll.