172 lines
5.2 KiB
C++
172 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Engine/AssetManager.h"
|
|
#include "Engine/DataAsset.h"
|
|
#include "LyraAssetManagerStartupJob.h"
|
|
#include "LyraAssetManager.generated.h"
|
|
|
|
class ULyraGameData;
|
|
class ULyraPawnData;
|
|
|
|
struct FLyraBundles
|
|
{
|
|
static const FName Equipped;
|
|
};
|
|
|
|
|
|
/**
|
|
* ULyraAssetManager
|
|
*
|
|
* Game implementation of the asset manager that overrides functionality and stores game-specific types.
|
|
* It is expected that most games will want to override AssetManager as it provides a good place for game-specific loading logic.
|
|
* This class is used by setting 'AssetManagerClassName' in DefaultEngine.ini.
|
|
*/
|
|
UCLASS(Config = Game)
|
|
class ULyraAssetManager : public UAssetManager
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
ULyraAssetManager();
|
|
|
|
// Returns the AssetManager singleton object.
|
|
static ULyraAssetManager& Get();
|
|
|
|
// Returns the asset referenced by a TSoftObjectPtr. This will synchronously load the asset if it's not already loaded.
|
|
template<typename AssetType>
|
|
static AssetType* GetAsset(const TSoftObjectPtr<AssetType>& AssetPointer, bool bKeepInMemory = true);
|
|
|
|
// Returns the subclass referenced by a TSoftClassPtr. This will synchronously load the asset if it's not already loaded.
|
|
template<typename AssetType>
|
|
static TSubclassOf<AssetType> GetSubclass(const TSoftClassPtr<AssetType>& AssetPointer, bool bKeepInMemory = true);
|
|
|
|
// Logs all assets currently loaded and tracked by the asset manager.
|
|
static void DumpLoadedAssets();
|
|
|
|
const ULyraGameData& GetGameData();
|
|
const ULyraPawnData* GetDefaultPawnData() const;
|
|
|
|
protected:
|
|
template <typename GameDataClass>
|
|
const GameDataClass& GetOrLoadTypedGameData(const TSoftObjectPtr<GameDataClass>& DataPath)
|
|
{
|
|
if (TObjectPtr<UPrimaryDataAsset> const * pResult = GameDataMap.Find(GameDataClass::StaticClass()))
|
|
{
|
|
return *CastChecked<GameDataClass>(*pResult);
|
|
}
|
|
|
|
// Does a blocking load if needed
|
|
return *CastChecked<const GameDataClass>(LoadGameDataOfClass(GameDataClass::StaticClass(), DataPath, GameDataClass::StaticClass()->GetFName()));
|
|
}
|
|
|
|
|
|
static UObject* SynchronousLoadAsset(const FSoftObjectPath& AssetPath);
|
|
static bool ShouldLogAssetLoads();
|
|
|
|
// Thread safe way of adding a loaded asset to keep in memory.
|
|
void AddLoadedAsset(const UObject* Asset);
|
|
|
|
//~UAssetManager interface
|
|
virtual void StartInitialLoading() override;
|
|
#if WITH_EDITOR
|
|
virtual void PreBeginPIE(bool bStartSimulate) override;
|
|
#endif
|
|
//~End of UAssetManager interface
|
|
|
|
UPrimaryDataAsset* LoadGameDataOfClass(TSubclassOf<UPrimaryDataAsset> DataClass, const TSoftObjectPtr<UPrimaryDataAsset>& DataClassPath, FPrimaryAssetType PrimaryAssetType);
|
|
|
|
protected:
|
|
|
|
// Global game data asset to use.
|
|
UPROPERTY(Config)
|
|
TSoftObjectPtr<ULyraGameData> LyraGameDataPath;
|
|
|
|
// Loaded version of the game data
|
|
UPROPERTY(Transient)
|
|
TMap<TObjectPtr<UClass>, TObjectPtr<UPrimaryDataAsset>> GameDataMap;
|
|
|
|
// Pawn data used when spawning player pawns if there isn't one set on the player state.
|
|
UPROPERTY(Config)
|
|
TSoftObjectPtr<ULyraPawnData> DefaultPawnData;
|
|
|
|
private:
|
|
// Flushes the StartupJobs array. Processes all startup work.
|
|
void DoAllStartupJobs();
|
|
|
|
// Sets up the ability system
|
|
void InitializeAbilitySystem();
|
|
void InitializeGameplayCueManager();
|
|
|
|
// Called periodically during loads, could be used to feed the status to a loading screen
|
|
void UpdateInitialGameContentLoadPercent(float GameContentPercent);
|
|
|
|
// The list of tasks to execute on startup. Used to track startup progress.
|
|
TArray<FLyraAssetManagerStartupJob> StartupJobs;
|
|
|
|
private:
|
|
|
|
// Assets loaded and tracked by the asset manager.
|
|
UPROPERTY()
|
|
TSet<TObjectPtr<const UObject>> LoadedAssets;
|
|
|
|
// Used for a scope lock when modifying the list of load assets.
|
|
FCriticalSection LoadedAssetsCritical;
|
|
};
|
|
|
|
|
|
template<typename AssetType>
|
|
AssetType* ULyraAssetManager::GetAsset(const TSoftObjectPtr<AssetType>& AssetPointer, bool bKeepInMemory)
|
|
{
|
|
AssetType* LoadedAsset = nullptr;
|
|
|
|
const FSoftObjectPath& AssetPath = AssetPointer.ToSoftObjectPath();
|
|
|
|
if (AssetPath.IsValid())
|
|
{
|
|
LoadedAsset = AssetPointer.Get();
|
|
if (!LoadedAsset)
|
|
{
|
|
LoadedAsset = Cast<AssetType>(SynchronousLoadAsset(AssetPath));
|
|
ensureAlwaysMsgf(LoadedAsset, TEXT("Failed to load asset [%s]"), *AssetPointer.ToString());
|
|
}
|
|
|
|
if (LoadedAsset && bKeepInMemory)
|
|
{
|
|
// Added to loaded asset list.
|
|
Get().AddLoadedAsset(Cast<UObject>(LoadedAsset));
|
|
}
|
|
}
|
|
|
|
return LoadedAsset;
|
|
}
|
|
|
|
template<typename AssetType>
|
|
TSubclassOf<AssetType> ULyraAssetManager::GetSubclass(const TSoftClassPtr<AssetType>& AssetPointer, bool bKeepInMemory)
|
|
{
|
|
TSubclassOf<AssetType> LoadedSubclass;
|
|
|
|
const FSoftObjectPath& AssetPath = AssetPointer.ToSoftObjectPath();
|
|
|
|
if (AssetPath.IsValid())
|
|
{
|
|
LoadedSubclass = AssetPointer.Get();
|
|
if (!LoadedSubclass)
|
|
{
|
|
LoadedSubclass = Cast<UClass>(SynchronousLoadAsset(AssetPath));
|
|
ensureAlwaysMsgf(LoadedSubclass, TEXT("Failed to load asset class [%s]"), *AssetPointer.ToString());
|
|
}
|
|
|
|
if (LoadedSubclass && bKeepInMemory)
|
|
{
|
|
// Added to loaded asset list.
|
|
Get().AddLoadedAsset(Cast<UObject>(LoadedSubclass));
|
|
}
|
|
}
|
|
|
|
return LoadedSubclass;
|
|
}
|