[UE] Bug: Mixin蓝图,蓝图是ts继承引擎类的运行会编辑器崩溃
前置阅读 | Pre-reading
Puer的版本 | Puer Version
Unreal_v1.0.8
UE的版本 | UE Version
5.4
发生在哪个平台 | Platform
Editor(win)
错误信息 | Error Message
ts继承引擎类没问题,继承代理蓝图的该蓝图没问题,mixin该蓝图则出现如下崩溃: LoginId:a3f4a1f84cd283bf7683a8bb909c56e2 EpicAccountId:e4c9ec8518b84eb89b293bc85428a0d8
Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp] [Line: 162] No object initializer found during construction.
UnrealEditor_CoreUObject!UObject::CreateDefaultSubobject() [D:\build++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp:163]
UnrealEditor_JsEnv!puerts::internal::FuncCallHelper<puerts::v8_impl::API,std::pair<UObject *,std::tuple<FName,UClass *,UClass ,bool,bool> >,0,0,1,0>::callMethod<UObject,UObject * (__cdecl UObject::)(FName,UClass *,UClass *,bool,bool),0,1,2,3,4>() [我的项目路径\Plugins\Puerts\Source\JsEnv\Public\StaticCall.hpp:801]
UnrealEditor_JsEnv!AutoRegisterForUE::AutoRegisterForUE'::2'::<lambda_1>::<lambda_invoker_cdecl>() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\Ext\UEExtension.cpp:96]
libnode
libnode
libnode
libnode
libnode
libnode
libnode
libnode
libnode
libnode
libnode
UnrealEditor_JsEnv!puerts::FJsEnvImpl::TsConstruct() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:2100]
UnrealEditor_JsEnv!puerts::FJsEnvImpl::TypeScriptInitial() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:2275]
UnrealEditor_JsEnv!puerts::FJsEnvImpl::TypeScriptInitial() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:2280]
UnrealEditor_JsEnv!puerts::FJsEnvImpl::FindOrAdd() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:1820]
UnrealEditor_JsEnv!puerts::FJsEnvImpl::FindOrAdd() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:1830]
UnrealEditor_JsEnv!puerts::FJsEnvImpl::InvokeMixinMethod() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JsEnvImpl.cpp:2249]
UnrealEditor_JsEnv!UJSGeneratedFunction::execCallMixin() [我的项目路径\Plugins\Puerts\Source\JsEnv\Private\JSGeneratedFunction.cpp:46]
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!AActor::BeginPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:4253]
UnrealEditor_Engine!AActor::DispatchBeginPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:4193]
UnrealEditor_Engine!AWorldSettings::NotifyBeginPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\WorldSettings.cpp:305]
UnrealEditor_Engine!AGameStateBase::HandleBeginPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\GameStateBase.cpp:228]
UnrealEditor_Engine!AGameModeBase::StartPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\GameModeBase.cpp:206]
UnrealEditor_Engine!UWorld::BeginPlay() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\World.cpp:5330]
UnrealEditor_Engine!UGameInstance::StartPlayInEditorGameInstance() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\GameInstance.cpp:568]
UnrealEditor_UnrealEd!UEditorEngine::CreateInnerProcessPIEGameInstance() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:3141]
UnrealEditor_UnrealEd!UEditorEngine::OnLoginPIEComplete_Deferred() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1590]
UnrealEditor_UnrealEd!UEditorEngine::CreateNewPlayInEditorInstance() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1853]
UnrealEditor_UnrealEd!UEditorEngine::StartPlayInEditorSession() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:2872]
UnrealEditor_UnrealEd!UEditorEngine::StartQueuedPlaySessionRequestImpl() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1167]
UnrealEditor_UnrealEd!UEditorEngine::StartQueuedPlaySessionRequest() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\PlayLevel.cpp:1068]
UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1902]
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
问题重现 | Bug reproduce
ts继承引擎类没问题,继承代理蓝图的该蓝图没问题,mixin该蓝图则出现如上崩溃:
排查下来是继承引擎类的ts构造函数中有如下CreateDefaultSubobject相关代码导致的,注释掉就不崩溃了,不注释mixin该代理蓝图子类会崩溃:
不建议两个混合使用。
可能之前我搞错了,这次发现只使用继承引擎类在构造函数Constructor()中使用如上注释的代码也会崩溃,我又验证了下用如下CreateDefaultSubobject代码在Call In Editor的时候调用,也出现类似如上的bug,感觉是CreateDefaultSubobject没有在引擎构造时调用,并且AsyncLoadingThreadEnabled开不开启ts构造都用不了CreateDefaultSubobject。
[2025.06.09-11.59.54:473][947]LogWindows: Error: appError called: Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp] [Line: 162] No object initializer found during construction.
[2025.06.09-11.59.54:473][947]LogWindows: Windows GetLastError: The operation completed successfully. (0) [2025.06.09-11.59.54:476][947]LogWindows: Error: === Critical error: === [2025.06.09-11.59.54:476][947]LogWindows: Error: [2025.06.09-11.59.54:476][947]LogWindows: Error: [2025.06.09-11.59.54:476][947]LogWindows: Error: [2025.06.09-11.59.54:476][947]LogWindows: Error: Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp] [Line: 162] [2025.06.09-11.59.54:476][947]LogWindows: Error: No object initializer found during construction. [2025.06.09-11.59.54:476][947]LogWindows: Error: [2025.06.09-11.59.54:486][947]LogExit: Executing StaticShutdownAfterError [2025.06.09-11.59.54:493][947]LogWindows: FPlatformMisc::RequestExit(1, WindowsErrorOutputDevice::Serialize.!GIsGuarded) [2025.06.09-11.59.54:493][947]LogWindows: FPlatformMisc::RequestExitWithStatus(1, 3, WindowsErrorOutputDevice::Serialize.!GIsGuarded) [2025.06.09-11.59.54:494][947]LogCore: Engine exit requested (reason: Win RequestExit)
这样写 https://github.com/chexiongsheng/BlockBreakerStarter/blob/master/TypeScript/TS_Player.ts#L17
mixin混合使用继承引擎类的确很多问题,我的情况是继承引擎类的蓝图子类做了mixin,导致了如下问题: 1、继承引擎类BeginPlay只在蓝图生效,这个倒是ts的BeginPlay逻辑创建新方法来给蓝图调用可以解决。 2、继承引擎类的构造函数中使用CreateDefaultSubobject,将不在引擎构造的时机导致崩溃,这没法解决,导致ts写默认的组件是undefined
想了解下对于继承引擎类的最佳实践是什么?mixin的最佳实践是什么?
这样写 https://github.com/chexiongsheng/BlockBreakerStarter/blob/master/TypeScript/TS_Player.ts#L17
CreateDefaultSubobject的问题我发了示例,用修饰器加。
至于最佳实践,按我自己的想法以及和多个项目交流的结果:别用“继承引擎类”,这会导致脚本和ue间耦合度加大。
再补充下mixin和继承引擎类混合使用的第三个问题: 比如说添加相机组件: FpsCamera: UE.CameraComponent; 在只有继承引擎类中,代理蓝图就直接根据代码添加相机组件并实例化了 当像我一样继承引擎类代理蓝图创建蓝图子类并Mixin子类后,添加的组件变量FpsCamera就undefined,而且构造函数中也无法CreateDefaultSubobject,所以两者混合使用很难走下去了