Unreal Engine C++ developer.
- I like creating various engine tools that simplify the development process.
- Feel free to email me at [email protected] or join telegram/discord chats for any questions.
Unreal Engine C++ developer.
You can save any UObject that is represented as an asset within a UPackage using this method: bool SaveToAsset(UObject* ObjectToSave) { UPackage* Package = ObjectToSave->GetPackage(); const FString PackageName = Package->GetName(); const FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension()); FSavePackageArgs SaveArgs; // This is specified just for example { SaveArgs.TopLevelFlags = RF_Public | RF_Standalone; SaveArgs.SaveFlags = SAVE_NoError; } const bool bSucceeded = UPackage::SavePackage(Package, nullptr, *PackageFileName, SaveArgs); if (!bSucceeded) { UE_LOG(LogTemp, Error, TEXT("Package '%s' wasn't saved!...
Note: This is an experimental article and may look strange as it compares two completely different concepts. But nevertheless, I think that they can be compared to some extent, which I did in this article. Smart pointers are typically compared to raw pointers , but this article will compare TUniquePtr, a type of smart pointer in Unreal Engine, and direct rvalue reference. I intentionally add “direct” to the rvalue reference term to make it more clear, because the rvalue reference can be applied to TUniquePtr itself in the same way and this can cause confusion....
There is a std::variant class template in the standard library that is essentially a type-safe union. It is generally used when we are not sure in advance which object should be populated from our list of object types, so we assume that one of the specified objects must be there at a time. Unreal Engine has an alternative implementation called TVariant that works the same, except that all the types in the declaring template parameter pack must be unique....
Unreal Engine has an alternative implementation of std::mutex called FCriticalSection which makes it possible for your data to be safely accessed from different threads. This takes the same approach, handling it with one thread locking until the other thread completes the necessary operations. There are two ways to handle lock/unlock logic. The first is low-level, which is used to directly lock and unlock threads. Use with caution due to possible deadlocks ....
This short article addresses the question of how to work with UObjects in a thread-safe way when passing them to some workers, asynchronous tasks, thread pools, or whatever else using a non-game thread. One of the crucial issues is garbage collection. When we pass a UObject that is not set to root directly to a background thread, it’s possible that the garbage collector may silently delete the passed UObject. Even if we frequently check the validity of the UObject (IsValidLowLevel()) on a background thread, we cannot guarantee that this object will remain alive, even just a few milliseconds after the check....