[PLUGIN] Savior

I’m submitting a plugin update for 5.3 and 5.4 which corrects the missing settings in 5.3 and adds the level options to the Load nodes.

1 Like

Hi,

Further to my previous post about correctly saving transforms of actors attached via the scene hierarchy or AttachToActor, there is another bug arising from the fix, which occurs when an attached actor is detached during play, then loaded again from savegame.

This happens because saving the relative transform of an unattached actor is the same as saving a world transform. But when loading objects Savior always applies relative transform. So the actor, being once again attached as per level layout, has a world transform applied as a relative transform, and the actor ends up in a different location.

Solution can be applied in Savior.h on line 2790:

I should also note, there is a bug that occurs on line 2785 in the call to SetupAttachment(), which throws a debug exception if the actor is already attached in the level editor. May need an additional step here to detach the actor, if it is attached in the level data, but not attached in the save data. And only call SetupAttachment() if the actor is not already attached correctly.

1 Like

Thanks, I will take a look as soon as possible.

Hey Bruno, I have purchased your plugin from the store and attempted to use it. It seems that any objects that i duplicated in the level with the alt key and moving them have all moved their location to the original duplicated object. Additionally, any items on the character have been removed upon load. I just need a little guidance on how to get things working. Thanks

Actors of same class, without a SGuid id are considered to be the same actor. Because they share the same class name.

There’s a guide on how to use SGuids in OP and marketplace page.

And then visibility of components on a character and static mesh components and variables that are attached to components on the player character that have changed after begin play are reverting to original state is that sguid related too?

Hi Bruno,

Excellent! Thank you very much, this is exactly what we needed! Thanks again for the effort and the awesome plugin, it works great.

Kind regards,

Wabo

I submitted a new version with these changes, for UE5.3 and 5.4.
Thanks

1 Like

I am having an issue where I attach actors/components to other components, save, and when the game is loaded they disconnect to the ground.

I have tried the save/load actor hierarchy nodes, and either I am not using them correctly or I misunderstand their use.

I have searched this thread for additional information and I still feel at a loss.

When someone had a similar issue with ships and sticking static meshes to them, you had replied the following:

“You can however map those meshes to a list of SoftReference | Bool map.
Whatever Ref in the map set to true would activate the static mesh component you need making it visible/loaded, and the plugin can auto save those Map properties just fine.” -[PLUGIN] Savior - #231 by BrUnO_XaVIeR

If this is the same solution for my situation, then i dont quite understand HOW its applicable, much less the way i should implement it.

How exactly, do I save and and then load a static mesh actor that is attached to another static mesh actor?

The problem is that “attached actors” aren’t really part of a hierarchy.

It’s some glue code from Epic.
I am very short of available time right now, but I will investigate a solution to this once I get the opportunity.

If you have a sample project with the exact attachment setup that you want to save (and isn’t working), that would reduce the debugging time in several weeks.

Since some types of attachments save correctly, but others ‘reset’ when the level is open… I would have to see exactly what you’re doing in your level.

I did some additional testing after you said level opening might effect things.

Saving, Quitting the game, Starting it back up, Leaving the Menu world and then Loading everything makes objects drop to the ground.

Saving, and then Loading works perfectly. Like a quick save/load

The only difference code wise would be opening the world. The saving and loading code is exactly the same.

I’ll see if i can recreate it in a blank project and then link it.

I was recreating my code, and found that i didn’t need to change worlds. So the recreation is even more simple than what i have, but the actual attachment method is the exact same i use in my own project.

All the code is just in the game instance and character.

First time sharing an example project, let me know if it doesnt work or something.

SaviorIssue.zip (4.7 MB)

1 Like

Thanks, I will take a look as soon as I can.

Due to some personal issues, I couldn’t have a look this weekend, but I will verify this as soon as possible.

all effort is appreciated, no problem.

I don’t think the “load game world” node supports auto loading this type of attachment yet:

I will investigate if this can be recorded by the save system, but it’s going to take a while.

i should have included a mention/example that BOTH

“Attach Actor To Component”
and
“Attach Component To Component”

nodes behave like this. I imagine its basically the same code that runs both of these nodes, but i figure it was worth a mention.

I’m trying to set up a system that allows unlimited saves by changing the slot’s file name. I’m getting crashes when trying to load a world after changing a level, but no crashes if I PIE straight in the same level.

I checked what’s up with visual studio debugger and it’s getting a bad reference to the world. This happens even when I stick a long delay after the beginplay of the gamemode, where I do the loading. Even then it only crashes after I’ve opened that level, and not if I play straight from it. The level is the correct one, the same where the save has happened.

So basically:
PIE Start in “Level” → Gamemode beginplay → Set slot file name for an instanced slot → Load game world → No crash

PIE Start in MainMenu → Open level “Level” → Gamemode beginplay → Set slot file name for an instanced slot → Load game world → Crash

Crash log (UE 5.4.3):

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000018

UnrealEditor_Savior!USavior::PrepareSlotToLoad() [D:\build\U5M-Marketplace\Sync\LocalBuilds\PluginTemp\HostProject\Plugins\Savior\Source\Savior\Private\Savior.cpp:409]
UnrealEditor_Savior!USavior::LoadGameWorld() [D:\build\U5M-Marketplace\Sync\LocalBuilds\PluginTemp\HostProject\Plugins\Savior\Source\Savior\Private\Savior.cpp:2411]
UnrealEditor_Savior!USavior::execLoadGameWorld() [d:\build\U5M-Marketplace\Sync\LocalBuilds\PluginTemp\HostProject\Plugins\Savior\Intermediate\Build\Win64\UnrealEditor\Inc\Savior\UHT\Savior.gen.cpp:3545]
UnrealEditor_CoreUObject!UFunction::Invoke() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Class.cpp:6847]
UnrealEditor_CoreUObject!UObject::CallFunction() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1139]
UnrealEditor_CoreUObject!UObject::ProcessContextOpcode() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:3086]
UnrealEditor_CoreUObject!ProcessLocalScriptFunction() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1206]
UnrealEditor_CoreUObject!UObject::ProcessInternal() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1304]
UnrealEditor_CoreUObject!UFunction::Invoke() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Class.cpp:6847]
UnrealEditor_CoreUObject!UObject::ProcessEvent() [D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:2144]
UnrealEditor_Engine!AActor::ProcessEvent() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:1092]
UnrealEditor_Engine!FLatentActionManager::TickLatentActionForObject() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LatentActionManager.cpp:318]
UnrealEditor_Engine!FLatentActionManager::ProcessLatentActions() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LatentActionManager.cpp:212]
UnrealEditor_Engine!AActor::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:1517]
UnrealEditor_Engine!AActor::TickActor() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:1493]
UnrealEditor_Engine!FActorTickFunction::ExecuteTick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:238]
UnrealEditor_Engine!FTickFunctionTask::DoTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:278]
UnrealEditor_Engine!TGraphTask<FTickFunctionTask>::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1235]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksNamedThread() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:760]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksUntilQuit() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:651]
UnrealEditor_Core!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2122]
UnrealEditor_Engine!FTickTaskSequencer::ReleaseTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:556]
UnrealEditor_Engine!FTickTaskManager::RunTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1583]
UnrealEditor_Engine!UWorld::RunTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:772]
UnrealEditor_Engine!UWorld::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1499]
UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:2015]
UnrealEditor_UnrealEd!UUnrealEdEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:550]
UnrealEditor!FEngineLoop::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5921]
UnrealEditor!GuardedMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:180]
UnrealEditor!GuardedMainWrapper() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:118]
UnrealEditor!LaunchWindowsStartup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:258]
UnrealEditor!WinMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:298]
UnrealEditor!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll

Am I doing something obviously wrong or is this a bug?

Thanks

1 Like

Thank you for the crash logs.
I will try to reproduce this assap!

1 Like

I’m submitting a hotfix for this issue for Unreal 5.4.
Once I can test it on earlier versions (5.3, etc), I will update them as well.

Usually Epic takes a few days to release updates.
Please let me know if you ever see this problem again.


Edit:
Epic already reviewed and released the update for UE5.4 ! :astonished:

1 Like