Okay, the title is odd. The gist is this:
- I want to create an editor extension that will bring up a window with an instance of an actor unique to that window (for its entire lifetime).
- This actor instance will never be saved nor loaded from any other package or on-disk file; it’s purely just a way to display the actor while the user customizes its data.
- The data itself is stored as a JSON file outside of the standard /Content/ dir (because… reasons).
- So, basically, I want to be able to customize an instance of this actor in a viewport while modifying the JSON config values, hit my button to save/load differing JSON files, then close the window, and go on my merry way.
I’ve probably spent a few weeks on figuring out how to properly handle this whole thing (and, by now, I wish I would have just written an external application to do it, but then I’d lose the viewport). For one thing: this is essentially a transient actor instance; it’s not to be saved nor loaded to disk. Beyond that, nothing that actually occurs within this editor has any practical effect on any other part of the game. It’s purely a visualization/authoring tool for my team (well, me) to customize base JSON files that get serialized/deserialized as-needed – this last part is all working and is copacetic.
I first tried just doing this by just creating a blueprint dummy file based on my primary C++ class for this actor, and then just extract data as properties changed in that editor. This… Did not work. The editor was very attached to any values set in a textbox or asset string reference dropbox (I could save the values out, but I could never load anything in, even when trying to manually set the properties – which were transient anyway).
So, then I looked at the StaticMeshEditor – since it’s got a viewport and a side-panel which is all I need in the world (oh to be as young and naive and hopeful as I was two weeks ago), but then realized that I was running into issues because that editor doesn’t operate on instanced data, it operates on an asset that exists on the local filesystem. So, hacking my way around that proved useless.
So, I re-wrote everything again, this time just started building off an FAssetToolkit-based window that launches a single tabbed container with one tab. Got the detail view all working (ish), and am now here:
That it appears and the detail view is customized more-or-less right (ignore the viewport, I could care less about that until everything else is resolved). So that’s neat. But: if this editor is opened at any time in the editor, it will always result in a exit-time editor (like UE4Editor, not this custom editor) crash. And I’m relatively certain at this point that it’s just due to some reference or pointer or distance relative somewhere not being properly cleaned up but… I AM SOOOO WORN OUT FROM THIS. Digging through the engine guts to figure out how to start this initially was rough, but digging through even more and more to figure out how to “actually” do things properly only to have crashes way, way deeper in the engine’s shutdown routine. It wounds me.
(Working on tools is my least favorite thing in the universe).
I’m sure that this is a somewhat unusual approach to an editor in UE, but the purpose of it is immutable, I just need to figure out how to get that purpose working. This isn’t really an AnswerHub thing since I’m sure it’s on my end somehow, but the dearth of information/documentation is making this exceedingly annoying. So here’s my last call-stack (and as I try and clean up more, the exact crash changes, but it’s always on shutdown).
LoginId:f0f3b82d4ae2ef5c62a9918e8cbc3f5d
EpicAccountId:017ebfc9f29f4134821504ead7d1034f
Access violation - code c0000005 (first/second chance not available)
UE4Editor_MechEditor!SharedPointerInternals::TReferenceControllerWithDeleter<AMech,SharedPointerInternals::DefaultDeleter<AMech> >::DestroyObject() [f:\joymachine\joyengine\engine\source\runtime\core\public emplates\sharedpointerinternals.h:110]
UE4Editor_MechEditor!FMechEditorModule::~FMechEditorModule()
UE4Editor_MechEditor!FMechEditorModule::`scalar deleting destructor'()
UE4Editor_Core!FModuleManager::UnloadModule() [f:\joymachine\joyengine\engine\source\runtime\core\private\modules\modulemanager.cpp:571]
UE4Editor_Core!FModuleManager::UnloadModulesAtShutdown() [f:\joymachine\joyengine\engine\source\runtime\core\private\modules\modulemanager.cpp:692]
UE4Editor!FEngineLoop::Exit() [f:\joymachine\joyengine\engine\source\runtime\launch\private\launchengineloop.cpp:2776]
UE4Editor!GuardedMain() [f:\joymachine\joyengine\engine\source\runtime\launch\private\launch.cpp:177]
UE4Editor!GuardedMainWrapper() [f:\joymachine\joyengine\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
UE4Editor!WinMain() [f:\joymachine\joyengine\engine\source\runtime\launch\private\windows\launchwindows.cpp:210]
UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253]
kernel32
ntdll
So, I get the callstack. There’s a shared pointer (the actor instance for the editor) that’s likely not being cleaned up before the object it is referring to is destroyed by, likely, the editor/world. I just can’t seem to figure out a good solution to get around it.
hugs,
trent