├── AsyncLoaderModule ├── AsyncLoaderModule.Build.cs ├── Private │ ├── AsyncLoader.cpp │ └── AsyncLoaderModule.cpp └── Public │ └── AsyncLoader.h ├── LICENSE └── README.md /AsyncLoaderModule/AsyncLoaderModule.Build.cs: -------------------------------------------------------------------------------- 1 | // ©2023 JDSherbert. All rights reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class AsyncLoaderModule : ModuleRules 6 | { 7 | public AsyncLoaderModule(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PrivateDependencyModuleNames.AddRange 10 | ( 11 | new string[] 12 | { 13 | "Core", 14 | "CoreUObject", 15 | "Engine" 16 | } 17 | ); 18 | } 19 | } -------------------------------------------------------------------------------- /AsyncLoaderModule/Private/AsyncLoader.cpp: -------------------------------------------------------------------------------- 1 | // ©2023 JDSherbert. All rights reserved. 2 | 3 | #include "AsyncLoaderModule/Public/AsyncLoader.h" 4 | 5 | #include 6 | #include 7 | 8 | template 9 | void UAsyncLoader::AsyncLoadObject(TSoftObjectPtr SoftPtr, T*& Out_LoadedObject) 10 | { 11 | if (!ValidateObject(SoftPtr)) 12 | { 13 | return; 14 | } 15 | 16 | FStreamableManager& StreamableManager = UAssetManager::Get().GetStreamableManager(); 17 | StreamableManager.RequestAsyncLoad 18 | (SoftPtr.ToSoftObjectPath(), [SoftPtr, &Out_LoadedObject]() 19 | { 20 | Out_LoadedObject = Cast(SoftPtr.Get()); 21 | } 22 | ); 23 | 24 | // Check if the object was already loaded synchronously 25 | if (StreamableManager.IsAsyncLoadComplete(SoftPtr.ToSoftObjectPath())) 26 | { 27 | Out_LoadedObject = Cast(SoftPtr.Get()); 28 | } 29 | } 30 | 31 | template 32 | void UAsyncLoader::AsyncLoadObject(TSoftObjectPtr SoftPtr, void(*Callback)(T* LoadedObject)) 33 | { 34 | if (!ValidateObject(SoftPtr)) 35 | { 36 | return; 37 | } 38 | 39 | FStreamableManager& StreamableManager = UAssetManager::Get().GetStreamableManager(); 40 | StreamableManager.RequestAsyncLoad 41 | (SoftPtr.ToSoftObjectPath(), [SoftPtr, Callback]() 42 | { 43 | T* LoadedObject = Cast(SoftPtr.Get()); 44 | if (Callback) 45 | { 46 | Callback(LoadedObject); 47 | } 48 | } 49 | ); 50 | 51 | // Check if the object was already loaded synchronously 52 | if (StreamableManager.IsAsyncLoadComplete(SoftPtr.ToSoftObjectPath())) 53 | { 54 | if (Callback) 55 | { 56 | Callback(Cast(SoftPtr.Get())); 57 | } 58 | } 59 | } 60 | 61 | template 62 | bool UAsyncLoader::ValidateObject(TSoftObjectPtr SoftPtr) 63 | { 64 | return (SoftPtr != nullptr && TIsDerivedFrom::IsDerived) ? true : false; 65 | } 66 | -------------------------------------------------------------------------------- /AsyncLoaderModule/Private/AsyncLoaderModule.cpp: -------------------------------------------------------------------------------- 1 | // ©2023 JDSherbert. All rights reserved. 2 | 3 | #include "Modules/ModuleManager.h" 4 | 5 | IMPLEMENT_MODULE(FDefaultModuleImpl, AsyncLoaderModule); -------------------------------------------------------------------------------- /AsyncLoaderModule/Public/AsyncLoader.h: -------------------------------------------------------------------------------- 1 | // ©2023 JDSherbert. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include "AsyncLoader.generated.h" 10 | 11 | DECLARE_DYNAMIC_DELEGATE_OneParam(FOnAsyncLoadComplete, UObject*, LoadedObject); 12 | 13 | /** 14 | * Async Load Tool 15 | * This class contains a set of static functions that makes asynchronous loading of UObjects more unified and easier to do. 16 | * Utilizes the internal streaming assets manager and throwaway lambda callbacks. 17 | * 18 | * @since Unreal Engine 5.2 19 | * @author JDSherbert 20 | */ 21 | UCLASS() 22 | class ASYNCLOADER_API UAsyncLoader final : public UBlueprintFunctionLibrary 23 | { 24 | GENERATED_BODY() 25 | 26 | public: 27 | 28 | /** 29 | * Attempts to load an asset at a defined path asynchronously, and store it in a variable on completion. \n 30 | * EXAMPLE: 31 | * @code 32 | * void MyFunction() 33 | * { 34 | * TSoftObjectPtr ObjectSoftPtr = SoftObjectPtrToYourObject; 35 | * USomeObject* SomeLoadedObject = nullptr; 36 | * UAsyncLoader::AsyncLoadObject(ObjectSoftPtr, SomeLoadedObject); 37 | * // Use the loaded object 38 | * if (SomeLoadedObject != nullptr) 39 | * { 40 | * // Do something with the loaded object 41 | * } 42 | * } 43 | * @endcode 44 | * 45 | * @note This is naturally latent, so always assess the validity of the asynchronously loaded object before use. 46 | * @tparam T The class of UObject to asynchronously load. Should be automatically determined by the SoftPtr reference. 47 | * @param SoftPtr The Soft Pointer to load. This is normally a path reference to the asset's template location in the project. 48 | * @param Out_LoadedObject The reference to a variable that will be populated with the loaded object. 49 | * 50 | * @since Unreal Engine 5.2 51 | * @author JDSherbert 52 | */ 53 | template 54 | UFUNCTION(BlueprintCallable, Category = "Async Loader") 55 | static void AsyncLoadObject(TSoftObjectPtr SoftPtr, T*& Out_LoadedObject); 56 | 57 | /** 58 | * Attempts to load an asset at a defined path asynchronously. 59 | * Will call the supplied function pointer on success, passing the loaded object pointer as a parameter. 60 | * Useful if you want to be notified when the load is completed. \n 61 | * EXAMPLE: 62 | * @code 63 | * void MyLoadCompleteCallback(UObject* LoadedObject) 64 | * { 65 | * // Handle the loaded object 66 | * if (LoadedObject != nullptr) 67 | * { 68 | * // Do something with the loaded object 69 | * } 70 | * } 71 | * 72 | * void MyFunction() 73 | * { 74 | * TSoftObjectPtr ObjectSoftPtr = SoftObjectPtrToYourObject; 75 | * UAsyncLoader::AsyncLoadObject(ObjectSoftPtr, &MyLoadCompleteCallback); 76 | * } 77 | * @endcode 78 | * 79 | * @note This is naturally latent, so always assess the validity of the asynchronously loaded object before use. 80 | * @tparam T The class of UObject to asynchronously load. Should be automatically determined by the SoftPtr reference. 81 | * @param SoftPtr The Soft Pointer to load. This is normally a path reference to the asset's template location in the project. 82 | * @param Callback The function to call on a success, with the LoadedObject as a parameter. 83 | * 84 | * @since Unreal Engine 5.2 85 | * @author JDSherbert 86 | */ 87 | template 88 | UFUNCTION(BlueprintCallable, Category = "Async Loader") 89 | static void AsyncLoadObject(TSoftObjectPtr SoftPtr, void(*Callback)(T* LoadedObject)); 90 | 91 | private: 92 | 93 | /** 94 | * Validates a soft pointer reference to ensure it is pointer to a valid memory address with the correct type. 95 | * 96 | * @param SoftPtr The Soft Pointer to load. This is normally a path reference to the asset's template location in the project. 97 | * @returns bool - true if valid. 98 | * 99 | * @since Unreal Engine 5.2 100 | * @author JDSherbert 101 | */ 102 | template 103 | bool ValidateObject(TSoftObjectPtr SoftPtr); 104 | }; 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 JDSherbert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/43964243/235778441-9dfb45ab-befd-480b-bc30-5eab5dc2efef.png) 2 | 3 | # Unreal Engine Async Load Tool 4 | 5 | 6 | 7 | 8 | Stars Badge 9 | Forks Badge 10 | Watchers Badge 11 | Issues Badge 12 | 13 | 14 | 15 | ----------------------------------------------------------------------- 16 | 17 | 18 | Unreal Engine Tool 19 | 20 | 21 | License 22 | 23 |

24 | 25 | ----------------------------------------------------------------------- 26 | ## Overview 27 | Compact Blueprint Function Library class that contains a set of static functions that makes asynchronous loading of UObjects more unified and easier to do. 28 | Utilizes the internal streaming assets manager and throwaway lambda callbacks. 29 | Note that this is naturally latent, so always assess the validity of the asynchronously loaded object before use. 30 | 31 | These functions are also available in blueprint! 32 | 33 | ----------------------------------------------------------------------- 34 | 35 | ### Why Asynchronously Load Anything? 36 | Loading game assets asynchronously offers several benefits: 37 | 38 | - Reduced Loading Times: We can preload what we need! 39 | - Improved Responsiveness: Asynchronous loading helps prevent the main thread from being blocked, allowing other processes to continue unimpeded. 40 | - Optimized Resource Usage: Loading assets asynchronously allows for better management of system resources and optimization. 41 | - Dynamic Loading and Unloading: Assets can be loaded or unloaded based on the player's location or progression, helping to conserve resources. 42 | - Streaming and Seamless Transitions: Asynchronous loading supports streaming of assets, allowing for seamless transitions between different parts of the game world. This is essential for maintaining a continuous and immersive experience without noticeable interruptions or loading screens. 43 | - Parallel Processing: While one set of assets is being loaded, other game-related tasks can be performed simultaneously, maximizing the utilization of available hardware resources. 44 | - Adaptability to Varying Hardware: Stability and resource delegation. 45 | 46 | In summary, loading game assets asynchronously contributes to a more responsive, efficient, and immersive gaming experience, particularly in scenarios where large and dynamic game worlds are involved. 47 | 48 | ----------------------------------------------------------------------- 49 | ### Using the Tool 50 | 51 | First, implement the this gameplay module into your project. 52 | 53 | Then, there are two ways to load with the tool: 54 | 1. Without Callback (Pointer Only) 55 | ```cpp 56 | template 57 | UFUNCTION(BlueprintCallable, Category = "Async Loader") 58 | static void AsyncLoadObject(TSoftObjectPtr SoftPtr, T*& Out_LoadedObject); 59 | ``` 60 | Attempts to load an asset at a defined path asynchronously, and store it in a variable on completion. 61 | ```cpp 62 | // EXAMPLE: 63 | void MyClass::MyFunction() 64 | { 65 | TSoftObjectPtr ObjectSoftPtr = SoftObjectPtrToYourObject; 66 | USomeObject* SomeLoadedObject = nullptr; 67 | UAsyncLoader::AsyncLoadObject(ObjectSoftPtr, SomeLoadedObject); 68 | // Use the loaded object 69 | if (SomeLoadedObject != nullptr) // Always check for nullptrs on asyncloaded objects 70 | { 71 | // Do something with the loaded object 72 | } 73 | } 74 | ``` 75 | 76 | 77 | 2. With Callback 78 | ```cpp 79 | template 80 | UFUNCTION(BlueprintCallable, Category = "Async Loader") 81 | static void AsyncLoadObject(TSoftObjectPtr SoftPtr, void(*Callback)(T* LoadedObject)); 82 | ``` 83 | Attempts to load an asset at a defined path asynchronously. 84 | Will call the supplied function pointer on success, passing the loaded object pointer as a parameter. 85 | Useful if you want to be notified when the load is completed. 86 | ```cpp 87 | // EXAMPLE: 88 | void MyClass::MyLoadCompleteCallback(UObject* LoadedObject) 89 | { 90 | // Handle the loaded object 91 | if (LoadedObject != nullptr) // Always check for nullptrs on asyncloaded objects 92 | { 93 | // Do something with the loaded object 94 | } 95 | } 96 | 97 | void MyClass::MyFunction() 98 | { 99 | TSoftObjectPtr ObjectSoftPtr = SoftObjectPtrToYourObject; 100 | UAsyncLoader::AsyncLoadObject(ObjectSoftPtr, &MyLoadCompleteCallback); 101 | } 102 | ``` 103 | 104 | 105 | ----------------------------------------------------------------------- 106 | 107 | --------------------------------------------------------------------------------