#pragma once #include "CoreMinimal.h" #include "Subsystems/GameInstanceSubsystem.h" #include "Engine/StreamableManager.h" #include "PreloadSubsystem.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPreloadComplete); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPreloadProgress, float, Progress); /** * Preloads assets before level transition to prevent streaming pop-in. * * Usage from Blueprint: * 1. Get this subsystem from GameInstance * 2. Bind OnPreloadComplete / OnPreloadProgress * 3. Call StartPreload with content paths to scan * 4. Poll GetProgress() for loading bar * 5. On complete, open your target level */ UCLASS() class SIMULORE_TIRSOVA_API UPreloadSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: /** * Preload all assets found in the given content directory paths (recursive). * Example paths: "/Game/ArchVis", "/Game/CollaborativeViewer" */ UFUNCTION(BlueprintCallable, Category = "Preload") void StartPreload(const TArray& ContentPaths); /** * Preload specific assets by soft object path. * Useful when you know exactly which heavy assets to load. */ UFUNCTION(BlueprintCallable, Category = "Preload") void PreloadAssets(const TArray& Assets); /** Current loading progress 0.0 to 1.0. Poll this from your loading widget. */ UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Preload") float GetProgress() const; /** Number of assets being loaded. */ UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Preload") int32 GetTotalAssetCount() const; UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Preload") bool IsPreloading() const; /** Fires when all assets finish loading. */ UPROPERTY(BlueprintAssignable, Category = "Preload") FOnPreloadComplete OnPreloadComplete; /** Fires each frame with current progress. Bind to update your loading bar. */ UPROPERTY(BlueprintAssignable, Category = "Preload") FOnPreloadProgress OnPreloadProgress; private: void BeginAsyncLoad(); void OnAssetsLoaded(); bool TickProgress(float DeltaTime); TSharedPtr StreamableHandle; TArray PendingAssets; FTSTicker::FDelegateHandle TickerHandle; int32 TotalAssets = 0; bool bIsPreloading = false; };