LoadSense Pro is designed with extensibility at its core. This guide covers advanced customization patterns for enterprise-grade implementations requiring custom loading logic, specialized UI behaviors, and deep system integration.
LoadSense Pro follows a separation of concerns design pattern:
ULoadingScreenSubsystem - Core state management and orchestrationULoadingScreenDataAsset & UMusicConfigDataAsset - Designer-configurable parametersILoadingScreenInterface - Extensible communication protocolWhile LoadSense Pro includes UWBP_LoadingScreen, production games often require specialized widgets:
Filepath: Source/YourProject/Public/UI/CustomLoadingWidget.h
Filename: CustomLoadingWidget.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Interface/LoadingScreenInterface.h"
#include "CustomLoadingWidget.generated.h"
UCLASS()
class YOURPROJECT_API UCustomLoadingWidget : public UUserWidget, public ILoadingScreenInterface
{
GENERATED_BODY()
public:
// ILoadingScreenInterface implementation
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Loading Screen")
void SetBackgroundImage(UTexture2D* NewTexture) override;
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Loading Screen")
void SetLoadingProgress(float Progress) override;
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Loading Screen")
void SetLoadingText(const FString& StatusText) override;
// Custom loading states for advanced games
UFUNCTION(BlueprintImplementableEvent, Category = "Custom Loading")
void OnLoadingPhaseChanged(ECustomLoadingPhase Phase);
UFUNCTION(BlueprintImplementableEvent, Category = "Custom Loading")
void OnMultiplayerSyncUpdate(int32 PlayersReady, int32 TotalPlayers);
protected:
virtual void NativeConstruct() override;
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
// Advanced progress tracking for complex asset loading
void UpdateDetailedProgress(const FString& CurrentOperation, float SubProgress);
// Custom animation system integration
void TriggerLoadingAnimation(const FName& AnimationName);
private:
// Performance monitoring for production builds
void TrackLoadingMetrics();
float LoadingStartTime = 0.0f;
UPROPERTY()
TMap<FString, float> OperationTimings;
};
For games requiring additional loading events beyond the standard interface:
Filepath: Source/YourProject/Public/Interface/ExtendedLoadingInterface.h
Filename: ExtendedLoadingInterface.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ExtendedLoadingInterface.generated.h"
UENUM(BlueprintType)
enum class ECustomLoadingPhase : uint8
{
AssetDiscovery,
AssetLoading,
WorldInitialization,
PlayerSpawning,
NetworkSynchronization,
GameSystemsInitialization,
Complete
};
USTRUCT(BlueprintType)
struct FLoadingMetrics
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
float TotalLoadTime = 0.0f;
UPROPERTY(BlueprintReadOnly)
int32 AssetsLoaded = 0;
UPROPERTY(BlueprintReadOnly)
float MemoryUsedMB = 0.0f;
UPROPERTY(BlueprintReadOnly)
FString BottleneckOperation;
};
UINTERFACE(MinimalAPI, Blueprintable)
class UExtendedLoadingInterface : public UInterface
{
GENERATED_BODY()
};
class YOURPROJECT_API IExtendedLoadingInterface
{
GENERATED_BODY()
public:
// Enhanced loading phase notifications
UFUNCTION(BlueprintImplementableEvent, Category = "Extended Loading")
void OnLoadingPhaseBegin(ECustomLoadingPhase Phase, const FString& PhaseDescription);
UFUNCTION(BlueprintImplementableEvent, Category = "Extended Loading")
void OnLoadingPhaseComplete(ECustomLoadingPhase Phase, float PhaseDuration);
// Multiplayer synchronization events
UFUNCTION(BlueprintImplementableEvent, Category = "Extended Loading")
void OnPlayerLoadingStateChanged(const FString& PlayerName, bool bIsReady);
// Performance and diagnostics
UFUNCTION(BlueprintImplementableEvent, Category = "Extended Loading")
void OnLoadingMetricsUpdate(const FLoadingMetrics& Metrics);
// Error recovery and retry mechanisms
UFUNCTION(BlueprintImplementableEvent, Category = "Extended Loading")
void OnLoadingError(const FString& ErrorCode, const FString& ErrorMessage, bool bCanRetry);
};
For games requiring dynamic audio systems during loading:
Filepath: Source/YourProject/Public/Data/AdvancedMusicConfig.h
Filename: AdvancedMusicConfig.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Data/MusicConfigDataAsset.h"
#include "Sound/SoundClass.h"
#include "AdvancedMusicConfig.generated.h"
UENUM(BlueprintType)
enum class EMusicTransitionType : uint8
{
Instant,
Crossfade,
FadeOutIn,
Stinger
};
USTRUCT(BlueprintType)
struct FDynamicMusicRule
{
GENERATED_BODY()
// Condition for rule activation
UPROPERTY(EditAnywhere, BlueprintReadOnly)
float LoadingProgressThreshold = 0.0f;
// Music to transition to
UPROPERTY(EditAnywhere, BlueprintReadOnly)
USoundBase* TargetTrack = nullptr;
// How to transition
UPROPERTY(EditAnywhere, BlueprintReadOnly)
EMusicTransitionType TransitionType = EMusicTransitionType::Crossfade;
// Transition duration
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (ClampMin = "0.1"))
float TransitionDuration = 2.0f;
};
UCLASS(BlueprintType)
class YOURPROJECT_API UAdvancedMusicConfig : public UMusicConfigDataAsset
{
GENERATED_BODY()
public:
// Dynamic music rules based on loading progress
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Dynamic Music")
TArray<FDynamicMusicRule> ProgressBasedRules;
// Adaptive audio mixing
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Advanced Audio")
USoundClass* LoadingMusicSoundClass = nullptr;
// Procedural variation
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Advanced Audio")
bool bUseProceduralVariation = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Advanced Audio",
meta = (EditCondition = "bUseProceduralVariation"))
float VariationIntensity = 0.1f;
// Platform-specific overrides
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Platform Optimization")
TMap<FString, float> PlatformVolumeMultipliers;
};
Filepath: Source/YourProject/Public/Data/EnvironmentLoadingConfig.h
Filename: EnvironmentLoadingConfig.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Data/LoadingScreenDataAsset.h"
#include "EnvironmentLoadingConfig.generated.h"
UENUM(BlueprintType)
enum class EGameEnvironment : uint8
{
Development,
Staging,
Production,
Demo
};
USTRUCT(BlueprintType)
struct FEnvironmentSpecificSettings
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
bool bShowDebugInfo = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
bool bAllowSkipping = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
float MinimumDisplayTime = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TArray<FString> AllowedSkipKeys;
// Telemetry and analytics
UPROPERTY(EditAnywhere, BlueprintReadOnly)
bool bEnableLoadingAnalytics = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FString AnalyticsEndpoint;
};
UCLASS(BlueprintType)
class YOURPROJECT_API UEnvironmentLoadingConfig : public ULoadingScreenDataAsset
{
GENERATED_BODY()
public:
// Environment-specific overrides
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Environment Settings")
TMap<EGameEnvironment, FEnvironmentSpecificSettings> EnvironmentSettings;
// A/B testing support
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "A/B Testing")
TArray<ULoadingScreenDataAsset*> VariantConfigurations;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "A/B Testing")
float VariantSplitRatio = 0.5f;
// Runtime configuration
FEnvironmentSpecificSettings GetCurrentEnvironmentSettings() const;
ULoadingScreenDataAsset* SelectVariantConfiguration() const;
};
For games requiring synchronized loading across multiple clients:
Filepath: Source/YourProject/Public/System/MultiplayerLoadingSubsystem.h
Filename: MultiplayerLoadingSubsystem.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "System/LoadingScreenSubsystem.h"
#include "Engine/NetDriver.h"
#include "MultiplayerLoadingSubsystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnPlayerReadyStateChanged,
const FString&, PlayerName, bool, bIsReady);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAllPlayersReady, float, TotalSyncTime);
USTRUCT(BlueprintType)
struct FPlayerLoadingState
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
FString PlayerName;
UPROPERTY(BlueprintReadOnly)
bool bIsConnected = false;
UPROPERTY(BlueprintReadOnly)
bool bAssetsLoaded = false;
UPROPERTY(BlueprintReadOnly)
bool bReadyToPlay = false;
UPROPERTY(BlueprintReadOnly)
float LoadingProgress = 0.0f;
UPROPERTY(BlueprintReadOnly)
FDateTime LastUpdateTime;
};
UCLASS()
class YOURPROJECT_API UMultiplayerLoadingSubsystem : public ULoadingScreenSubsystem
{
GENERATED_BODY()
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
// Multiplayer synchronization methods
UFUNCTION(BlueprintCallable, Category = "Multiplayer Loading")
void StartSynchronizedLoading(ULoadingScreenDataAsset* LoadingData,
float MaxWaitTime = 30.0f);
UFUNCTION(BlueprintCallable, Category = "Multiplayer Loading")
void ReportPlayerReady(const FString& PlayerName);
UFUNCTION(BlueprintPure, Category = "Multiplayer Loading")
bool AreAllPlayersReady() const;
UFUNCTION(BlueprintPure, Category = "Multiplayer Loading")
TArray<FPlayerLoadingState> GetPlayerLoadingStates() const;
// Network resilience
UFUNCTION(BlueprintCallable, Category = "Multiplayer Loading")
void HandlePlayerDisconnected(const FString& PlayerName);
UFUNCTION(BlueprintCallable, Category = "Multiplayer Loading")
void SetLoadingTimeout(float TimeoutSeconds);
// Events
UPROPERTY(BlueprintAssignable, Category = "Multiplayer Events")
FOnPlayerReadyStateChanged OnPlayerReadyStateChanged;
UPROPERTY(BlueprintAssignable, Category = "Multiplayer Events")
FOnAllPlayersReady OnAllPlayersReady;
protected:
// Network message handling
UFUNCTION(Server, Reliable)
void ServerUpdatePlayerProgress(const FString& PlayerName, float Progress);
UFUNCTION(NetMulticast, Reliable)
void MulticastPlayerStateUpdate(const FPlayerLoadingState& PlayerState);
// Timeout management
void CheckSynchronizationTimeout();
void ForceStartWithIncompleteTeam();
private:
UPROPERTY()
TMap<FString, FPlayerLoadingState> PlayerStates;
FTimerHandle SyncTimeoutTimer;
float MaxSynchronizationWaitTime = 30.0f;
float SynchronizationStartTime = 0.0f;
bool bIsSynchronizedLoading = false;
bool bAllowIncompleteStart = true;
};
Filepath: Source/YourProject/Public/System/StreamingAwareLoadingSubsystem.h
Filename: StreamingAwareLoadingSubsystem.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "System/LoadingScreenSubsystem.h"
#include "Engine/World.h"
#include "Engine/WorldComposition.h"
#include "StreamingAwareLoadingSubsystem.generated.h"
USTRUCT(BlueprintType)
struct FStreamingLevelInfo
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
FString LevelName;
UPROPERTY(BlueprintReadOnly)
float LoadingProgress = 0.0f;
UPROPERTY(BlueprintReadOnly)
bool bIsVisible = false;
UPROPERTY(BlueprintReadOnly)
float EstimatedLoadTime = 0.0f;
};
UCLASS()
class YOURPROJECT_API UStreamingAwareLoadingSubsystem : public ULoadingScreenSubsystem
{
GENERATED_BODY()
public:
// Enhanced loading with streaming level awareness
UFUNCTION(BlueprintCallable, Category = "Streaming Loading")
void LoadMapWithStreamingOptimization(ULoadingScreenDataAsset* LoadingData,
const TArray<FString>& PreloadStreamingLevels);
// Real-time streaming level monitoring
UFUNCTION(BlueprintPure, Category = "Streaming Loading")
TArray<FStreamingLevelInfo> GetStreamingLevelStates() const;
// Predictive loading based on player data
UFUNCTION(BlueprintCallable, Category = "Streaming Loading")
void PreloadBasedOnPlayerHistory(const FVector& PlayerStartLocation,
float PreloadRadius = 5000.0f);
protected:
// Advanced progress calculation including streaming levels
float CalculateStreamingAwareProgress() const;
// Memory pressure monitoring
void MonitorMemoryPressure();
void HandleMemoryPressure(float MemoryUsagePercent);
// Adaptive quality based on performance
void AdjustLoadingQuality();
private:
UPROPERTY()
TArray<FStreamingLevelInfo> StreamingLevels;
// Performance monitoring
FTimerHandle MemoryMonitorTimer;
float BaselineMemoryUsage = 0.0f;
// Adaptive loading thresholds
float MemoryPressureThreshold = 0.85f;
bool bAdaptiveQualityEnabled = true;
};
Filepath: Source/YourProject/Public/LoadingScreenFunctionLibrary.h
Filename: LoadingScreenFunctionLibrary.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Data/LoadingScreenDataAsset.h"
#include "LoadingScreenFunctionLibrary.generated.h"
UCLASS()
class YOURPROJECT_API ULoadingScreenFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
// Utility functions for designers
UFUNCTION(BlueprintCallable, Category = "Loading Screen Utilities",
CallInEditor = true)
static ULoadingScreenDataAsset* CreateLoadingDataAssetFromTemplate(
const FString& MapName,
ULoadingScreenDataAsset* Template);
UFUNCTION(BlueprintPure, Category = "Loading Screen Utilities")
static float EstimateLoadingTime(const FString& MapName,
bool bIncludeStreamingLevels = true);
UFUNCTION(BlueprintCallable, Category = "Loading Screen Utilities")
static void PrewarmLoadingAssets(ULoadingScreenDataAsset* LoadingData);
// Platform-specific optimizations
UFUNCTION(BlueprintPure, Category = "Loading Screen Utilities")
static ULoadingScreenDataAsset* GetPlatformOptimizedConfig(
ULoadingScreenDataAsset* BaseConfig);
// Analytics integration
UFUNCTION(BlueprintCallable, Category = "Loading Screen Analytics")
static void ReportLoadingMetrics(const FString& MapName,
float LoadTime, const TMap<FString, FString>& CustomData);
// Error recovery
UFUNCTION(BlueprintCallable, Category = "Loading Screen Utilities")
static bool AttemptLoadingRecovery(const FString& ErrorCode);
private:
// Platform detection utilities
static bool IsRunningOnMobile();
static bool IsRunningOnConsole();
static float GetPlatformMemoryScale();
};
Filepath: Source/YourProject/Public/Debug/LoadingScreenDebugComponent.h
Filename: LoadingScreenDebugComponent.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "System/LoadingScreenSubsystem.h"
#include "LoadingScreenDebugComponent.generated.h"
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class YOURPROJECT_API ULoadingScreenDebugComponent : public UActorComponent
{
GENERATED_BODY()
public:
ULoadingScreenDebugComponent();
// Debug visualization
UFUNCTION(BlueprintCallable, Category = "Loading Debug")
void EnableDebugOverlay(bool bEnable = true);
UFUNCTION(BlueprintCallable, Category = "Loading Debug", CallInEditor = true)
void SimulateSlowLoading(float SlowdownFactor = 2.0f);
UFUNCTION(BlueprintCallable, Category = "Loading Debug")
void LogCurrentLoadingState();
// Performance profiling
UFUNCTION(BlueprintCallable, Category = "Loading Debug")
void StartProfilingSession(const FString& SessionName);
UFUNCTION(BlueprintCallable, Category = "Loading Debug")
void EndProfilingSession();
// Memory tracking
UFUNCTION(BlueprintPure, Category = "Loading Debug")
float GetCurrentMemoryUsageMB() const;
UFUNCTION(BlueprintCallable, Category = "Loading Debug")
void DumpMemoryStats();
protected:
virtual void BeginPlay() override;
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
private:
void DrawDebugInfo();
void UpdatePerformanceMetrics();
bool bDebugOverlayEnabled = false;
FString CurrentProfilingSession;
TMap<FString, float> ProfilingData;
// Performance tracking
float FrameTimeAccumulator = 0.0f;
int32 FrameCount = 0;
float AverageFrameTime = 0.0f;
};
Filepath: Source/YourProject/Public/Analytics/LoadingAnalyticsManager.h
Filename: LoadingAnalyticsManager.h
// Copyright Seven-Mountains-Labs, Tim Koepsel - 2024 All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "LoadingAnalyticsManager.generated.h"
USTRUCT(BlueprintType)
struct FLoadingEvent
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
FString EventType;
UPROPERTY(BlueprintReadOnly)
FString MapName;
UPROPERTY(BlueprintReadOnly)
float Duration = 0.0f;
UPROPERTY(BlueprintReadOnly)
FDateTime Timestamp;
UPROPERTY(BlueprintReadOnly)
TMap<FString, FString> CustomProperties;
UPROPERTY(BlueprintReadOnly)
FString Platform;
UPROPERTY(BlueprintReadOnly)
FString BuildVersion;
};
UCLASS()
class YOURPROJECT_API ULoadingAnalyticsManager : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
// Event tracking
UFUNCTION(BlueprintCallable, Category = "Loading Analytics")
void TrackLoadingStarted(const FString& MapName,
const TMap<FString, FString>& CustomData = TMap<FString, FString>());
UFUNCTION(BlueprintCallable, Category = "Loading Analytics")
void TrackLoadingCompleted(const FString& MapName, float Duration,
bool bSuccessful = true);
UFUNCTION(BlueprintCallable, Category = "Loading Analytics")
void TrackLoadingError(const FString& MapName, const FString& ErrorCode,
const FString& ErrorMessage);
// Performance metrics
UFUNCTION(BlueprintCallable, Category = "Loading Analytics")
void TrackPerformanceMetrics(float FrameRate, float MemoryUsage,
float LoadingProgress);
// User behavior
UFUNCTION(BlueprintCallable, Category = "Loading Analytics")
void TrackUserInteraction(const FString& InteractionType,
const FString& Context);
protected:
// Backend communication
void SendEventsToBackend();
void QueueEvent(const FLoadingEvent& Event);
// Data persistence
void SaveEventCache();
void LoadEventCache();
private:
UPROPERTY()
TArray<FLoadingEvent> PendingEvents;
FTimerHandle FlushTimer;
static constexpr float FlushInterval = 30.0f;
FString AnalyticsEndpoint;
bool bAnalyticsEnabled = true;
};
// In your game's loading widget
void UCustomGameLoadingWidget::SetLoadingProgress(float Progress)
{
// Map generic progress to game-specific phases
if (Progress < 0.2f)
{
OnLoadingPhaseChanged(ECustomLoadingPhase::AssetDiscovery);
UpdateStatusText("Scanning game world...");
}
else if (Progress < 0.5f)
{
OnLoadingPhaseChanged(ECustomLoadingPhase::AssetLoading);
UpdateStatusText("Loading game assets...");
}
else if (Progress < 0.8f)
{
OnLoadingPhaseChanged(ECustomLoadingPhase::WorldInitialization);
UpdateStatusText("Initializing world systems...");
}
else
{
OnLoadingPhaseChanged(ECustomLoadingPhase::Complete);
UpdateStatusText("Preparing game session...");
}
// Update base progress bar
Super::SetLoadingProgress(Progress);
}
// In your loading subsystem extension
void UYourCustomLoadingSubsystem::StartLoadingScreen()
{
// Call parent implementation
Super::StartLoadingScreen();
// Track loading start
if (ULoadingAnalyticsManager* Analytics = GetGameInstance()->GetSubsystem<ULoadingAnalyticsManager>())
{
TMap<FString, FString> CustomData;
CustomData.Add("LoadType", CurrentLoadingData ?
(CurrentLoadingData->LoadType == EMapLoadType::Asynchronous ? "Async" : "Sync") : "Unknown");
CustomData.Add("PlayerCount", FString::FromInt(GetNumberOfPlayers()));
Analytics->TrackLoadingStarted(TargetMapName, CustomData);
}
}
LoadSense Pro’s modular architecture enables these advanced customizations while maintaining system reliability and performance. The interface-driven design ensures your customizations remain compatible across plugin updates.
References: