Quartz UI ↗
Browse docs
On this page
Private preview · 0.57.0-devView Markdown

QuartzUISound: declaration reference

0.57.0-dev · beta source documentation. Native, Blueprint, Editor and rendering examples are source-reviewed, not executed in Unreal during this scan. See validation and limits.

Pinned source (source: Source/QuartzUIRuntime/Public/QuartzUISound.h) · integration recipe · practical guide

EQuartzUISoundRequestResult

Public type. Outcome of one semantic UI-sound request at the project-owned routing boundary.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L15)

FQuartzUISoundRequested

Public delegate. Blueprint listener for one exact local player's semantic UI-sound request.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L24)

FQuartzUINativeSoundRequested

Public delegate. Native listener equivalent used by project audio adapters.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L27)

FQuartzUISoundPolicy

Internal type. Strict tag and burst policy shared by runtime dispatch and automation.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. This named helper is runtime-owned; inspect/use it through the owner above rather than constructing it in gameplay.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L30)

FQuartzUISoundEntry

Public type. One semantic cue mapped to an optional lazily loaded Unreal sound asset.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L51)

UQuartzUISoundHandler

Public type. Swappable per-player backend for one resolved semantic UI sound.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L75)

UQuartzUISoundSet

Public type. Small reusable metadata collection; every referenced sound remains soft.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L121)

UQuartzUISoundSubsystem

Public type. Exact-local-player UI-audio router. Runtime sound sets resolve newest-first above the project default. The resolving set selects a cached backend handler, while native and Blueprint listeners remain a zero-asset project integration tier.

Prerequisites / integration: Exact-player view plus native asset/source ownership; GAS additionally requires GameplayAbilities. Use the QuartzUISound recipe in the host module QuartzUIRuntime.

Minimal example / lifecycle: Map ui.confirm then request quartzui.sound.play. Balance set push/remove; subsystem shuts handlers/loads down.

Avoid: Double playback through both listener and handler. Match the exact declaration below; dependent DTOs/enums are values used by this owner, not independent systems.

Exact source line (source: Source/QuartzUIRuntime/Public/QuartzUISound.h#L149)

Complete header

Source snapshot, not an additional example. Unreal annotations distinguish exposed Blueprint nodes from native-only/private methods.

#pragma once

#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "Subsystems/LocalPlayerSubsystem.h"

#include "QuartzUISound.generated.h"

struct FStreamableHandle;
class ULocalPlayer;
class USoundBase;

/** Outcome of one semantic UI-sound request at the project-owned routing boundary. */
UENUM(BlueprintType)
enum class EQuartzUISoundRequestResult : uint8
{
	Routed,
	InvalidTag,
	Unhandled,
	RateLimited
};

/** Blueprint listener for one exact local player's semantic UI-sound request. */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FQuartzUISoundRequested, FName, SoundTag);

/** Native listener equivalent used by project audio adapters. */
DECLARE_MULTICAST_DELEGATE_OneParam(FQuartzUINativeSoundRequested, FName);

/** Strict tag and burst policy shared by runtime dispatch and automation. */
class QUARTZUIRUNTIME_API FQuartzUISoundPolicy final
{
public:
	static constexpr int32 MaxRequestsPerSecond = 32;
	static constexpr double RateLimitWindowSeconds = 1.0;

	/** Accepts lowercase dotted project language such as ui.confirm or menu.back. */
	static bool IsValidSoundTag(FName SoundTag);

	/** Strictly decodes the exact {"sound":"..."} reserved endpoint payload. */
	static bool TryParseSoundRequest(const FString& PayloadJson, FName& OutSoundTag);

	/** Fixed-window limiter with explicit caller-owned state for deterministic tests. */
	static bool TryConsumeRateLimit(
		double CurrentTimeSeconds,
		double& InOutWindowStartSeconds,
		int32& InOutRequestCount);
};

/** One semantic cue mapped to an optional lazily loaded Unreal sound asset. */
USTRUCT(BlueprintType)
struct QUARTZUIRUNTIME_API FQuartzUISoundEntry
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QuartzUI|Sound")
	FName SoundTag;

	/** A soft reference keeps the actual sound out of startup memory. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QuartzUI|Sound")
	TSoftObjectPtr<USoundBase> Sound;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QuartzUI|Sound", meta = (ClampMin = "0.0", ClampMax = "4.0"))
	float VolumeMultiplier = 1.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QuartzUI|Sound", meta = (ClampMin = "0.125", ClampMax = "4.0"))
	float PitchMultiplier = 1.0f;

	/** Preload only small, latency-critical cues such as navigation and confirm. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QuartzUI|Sound")
	bool bPreload = false;
};

/** Swappable per-player backend for one resolved semantic UI sound. */
UCLASS(Blueprintable)
class QUARTZUIRUNTIME_API UQuartzUISoundHandler : public UObject
{
	GENERATED_BODY()

public:
	/** Initializes this cached handler for one exact local player. */
	UFUNCTION(BlueprintNativeEvent, Category = "QuartzUI|Sound")
	void Initialize(ULocalPlayer* LocalPlayer);
	virtual void Initialize_Implementation(ULocalPlayer* LocalPlayer);

	/** Accepts a resolved cue and returns whether this backend handled it. */
	UFUNCTION(BlueprintNativeEvent, Category = "QuartzUI|Sound")
	bool HandleSound(FName SoundTag, const FQuartzUISoundEntry& Entry);
	virtual bool HandleSound_Implementation(
		FName SoundTag,
		const FQuartzUISoundEntry& Entry);

	/** Starts a load only for entries explicitly marked for preload. */
	virtual void PreloadSound(const FQuartzUISoundEntry& Entry);

	/** Cancels backend work before its owning player subsystem is released. */
	virtual void Shutdown();

protected:
	virtual void BeginDestroy() override;

	ULocalPlayer* GetLocalPlayer() const { return OwningLocalPlayer.Get(); }

private:
	bool RequestSoundLoad(const FQuartzUISoundEntry& Entry, bool bPlayWhenReady);
	void HandleSoundLoaded(FName SoundTag);
	void PlayLoadedSound(const FQuartzUISoundEntry& Entry, USoundBase* Sound);
	void CancelLoads();

	TWeakObjectPtr<ULocalPlayer> OwningLocalPlayer;
	TMap<FName, TSharedPtr<FStreamableHandle>> LoadHandles;
	TMap<FName, FQuartzUISoundEntry> RequestedEntries;
	TMap<FName, FSoftObjectPath> LoadedSoundPaths;
	TSet<FName> PendingPlayTags;

	UPROPERTY(Transient)
	TMap<FName, TObjectPtr<USoundBase>> LoadedSounds;
};

/** Small reusable metadata collection; every referenced sound remains soft. */
UCLASS(BlueprintType)
class QUARTZUIRUNTIME_API UQuartzUISoundSet final : public UDataAsset
{
	GENERATED_BODY()

public:
	static constexpr int32 MaxSoundEntries = 128;

	/** Optional backend override for every entry resolved from this set. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "QuartzUI|Sound")
	TSoftClassPtr<UQuartzUISoundHandler> HandlerClass;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "QuartzUI|Sound")
	TArray<FQuartzUISoundEntry> Sounds;

	UFUNCTION(BlueprintPure, Category = "QuartzUI|Sound")
	bool HasSound(FName SoundTag) const;

	const FQuartzUISoundEntry* FindSound(FName SoundTag) const;
};

/**
 * Exact-local-player UI-audio router.
 *
 * Runtime sound sets resolve newest-first above the project default. The
 * resolving set selects a cached backend handler, while native and Blueprint
 * listeners remain a zero-asset project integration tier.
 */
UCLASS(BlueprintType)
class QUARTZUIRUNTIME_API UQuartzUISoundSubsystem final : public ULocalPlayerSubsystem
{
	GENERATED_BODY()

public:
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	virtual void Deinitialize() override;

	/** Adds one highest-precedence sound set for this exact local player. */
	UFUNCTION(BlueprintCallable, Category = "QuartzUI|Sound")
	bool PushSoundSet(UQuartzUISoundSet* SoundSet);

	/** Removes the newest matching pushed set, revealing the previous mapping. */
	UFUNCTION(BlueprintCallable, Category = "QuartzUI|Sound")
	bool RemoveSoundSet(UQuartzUISoundSet* SoundSet);

	/** Resolves and emits one validated semantic cue for this exact local player. */
	UFUNCTION(BlueprintCallable, Category = "QuartzUI|Sound")
	EQuartzUISoundRequestResult RequestSound(FName SoundTag);

	UPROPERTY(BlueprintAssignable, Category = "QuartzUI|Sound")
	FQuartzUISoundRequested OnSoundRequested;

	FQuartzUINativeSoundRequested& OnNativeSoundRequested() { return NativeSoundRequested; }

private:
	void EnsureDefaultSoundSet();
	void PreloadSoundSet(const UQuartzUISoundSet* SoundSet);
	const FQuartzUISoundEntry* FindSoundEntry(
		FName SoundTag,
		const UQuartzUISoundSet*& OutSoundSet) const;
	UQuartzUISoundHandler* ResolveHandler(const UQuartzUISoundSet* SoundSet);
	UQuartzUISoundHandler* GetOrCreateHandler(UClass* HandlerClass);
	bool HasSoundListenerTier() const;

	FQuartzUINativeSoundRequested NativeSoundRequested;

	UPROPERTY(Transient)
	TObjectPtr<UQuartzUISoundSet> DefaultSoundSet;

	UPROPERTY(Transient)
	TArray<TObjectPtr<UQuartzUISoundSet>> SoundSetStack;

	UPROPERTY(Transient)
	TArray<TObjectPtr<UQuartzUISoundHandler>> HandlerInstances;

	bool bDefaultSoundSetResolved = false;
	double RateLimitWindowStartSeconds = -1.0;
	int32 RateLimitRequestCount = 0;
};