-
Notifications
You must be signed in to change notification settings - Fork 70
Some properties are overwritten by the old CDO on reinstancing #39
Description
[UClass, Blueprintable, BlueprintType]
public class SharpActor : AActor
{
[UProperty, EditAnywhere, BlueprintReadWrite]
public int SomeValue { get; set; }
public override void Initialize(FObjectInitializer initializer)
{
SomeValue = 10;
AllowTickBeforeBeginPlay = true;
}
}- Create the above C# actor.
- Create a blueprint which parents that class.
- Reopen the editor to get a clean state.
- Open the blueprint editor it should have SomeValue as 10 and AllowTickBeforeBeginPlay should be true (checked).
In the C# code change SomeValue to 5 and AllowTickBeforeBeginPlay to false and then recompile the C# code so that it hotreloads. The blueprint will correctly update SomeValue to 5 (unless it has been changed in the details panel to be non-default, which is again correct behavior). However, AllowTickBeforeBeginPlay will still show as being true and will now have the yellow icon/button next to to signify it is no longer the default value. This is incorrect. AllowTickBeforeBeginPlay should now be false and there shouldn't be any default value modified signifier.
This issue stems from the object reinstancing code. Property values from the old CDO are copied over to the new CDO. This occurs in UEngine::CopyPropertiesForUnrelatedObjects.
Look into what determines which values should be copied over, we may need to do custom re-instancing to filter out copying of values which are set to default?
Callstack for the property copy on child blueprints (this happens first):
UE4Editor-Engine.dll!UEngine::CopyPropertiesForUnrelatedObjects(UObject * OldObject, UObject * NewObject, UEngine::FCopyPropertiesForUnrelatedObjectsParams Params) Line 13491 C++
UE4Editor-UnrealEd.dll!ReplaceActorHelper(UObject * OldObject, UClass * OldClass, UObject * & NewUObject, UClass * NewClass, TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0> > & OldToNewInstanceMap, TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0> > & InOldToNewClassMap, AActor * OldActor, TMap<FSoftObjectPath,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<FSoftObjectPath,UObject *,0> > & ReinstancedObjectsWeakReferenceMap, TMap<UObject *,FActorAttachmentData,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,FActorAttachmentData,0> > & ActorAttachmentData, TArray<FActorReplacementHelper,FDefaultAllocator> & ReplacementActors, bool bPreserveRootComponent, bool & bSelectionChanged) Line 1816 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReplaceInstancesOfClass_Inner(TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0> > & InOldToNewClassMap, UObject * InOriginalCDO, TSet<UObject *,DefaultKeyFuncs<UObject *,0>,FDefaultSetAllocator> * ObjectsThatShouldUseOldStuff, bool bClassObjectReplaced, bool bPreserveRootComponent, bool bArchetypesAreUpToDate) Line 2013 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::BatchReplaceInstancesOfClass(TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0> > & InOldToNewClassMap, bool bArchetypesAreUpToDate) Line 1471 C++
UE4Editor-Kismet.dll!FBlueprintCompilationManagerImpl::FlushReinstancingQueueImpl() Line 1085 C++
UE4Editor-Kismet.dll!FBlueprintCompilationManagerImpl::CompileSynchronouslyImpl(const FBPCompileRequest & Request) Line 203 C++
UE4Editor-UnrealEd.dll!FKismetEditorUtilities::CompileBlueprint(UBlueprint * BlueprintObj, EBlueprintCompileOptions CompileFlags, FCompilerResultsLog * pResults) Line 745 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::CompileChildren() Line 603 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReinstanceObjects(bool bForceAlwaysReinstance) Line 737 C++
UE4Editor-USharp.dll!Export_SharpHotReloadUtils_ReinstanceClass(FSharpHotReloadClassReinstancer * Reinstancer) Line 45 C++
[Managed to Native Transition]
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.ManagedUnrealTypes.BuildTypes() Line 907 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.ManagedUnrealTypes.Load() Line 63 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.Native.NativeFunctions.OnNativeFunctionsRegistered() Line 189 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.Native.NativeFunctions.RegisterFunctions(System.IntPtr registerFunctionsAddr) Line 99 C#
UnrealEngine.Runtime.dll!UnrealEngine.EntryPoint.DllMain(string arg) Line 70 C#
[Native to Managed Transition]
[Managed to Native Transition]
Loader.dll!UnrealEngine.AssemblyLoader.Load() Line 475 C#
[AppDomain (DefaultDomain�, #1) -> AppDomain (Domain30654212 4�, #6)]
Loader.dll!UnrealEngine.EntryPoint.ReloadAppDomain() Line 249 C#
Loader.dll!UnrealEngine.EntryPoint.ReloadAppDomain.AnonymousMethod__0() Line 195 C#
Loader.dll!UnrealEngine.GameThreadHelper.Tick(float deltaTime) Line 672 C#
[Native to Managed Transition]
UE4Editor-USharp.dll!FTickerDelegateWrapper::Tick(float DeltaTime) Line 9 C++
UE4Editor-Core.dll!FTicker::Tick(float DeltaTime) Line 98 C++
UE4Editor.exe!FEngineLoop::Tick() Line 3669 C++
UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 166 C++
UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 209 C++
UE4Editor.exe!__scrt_common_main_seh() Line 283 C++
kernel32.dll!00000000778b59cd() Unknown
ntdll.dll!0000000077a1385d() Unknown
Callstack for the property copy on instanced objects in the world which can also be instanced C# actors as opposed to blueprint which also exhibit the same issues:
UE4Editor-Engine.dll!UEngine::CopyPropertiesForUnrelatedObjects(UObject * OldObject, UObject * NewObject, UEngine::FCopyPropertiesForUnrelatedObjectsParams Params) Line 13491 C++
UE4Editor-UnrealEd.dll!ReplaceActorHelper(UObject * OldObject, UClass * OldClass, UObject * & NewUObject, UClass * NewClass, TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0> > & OldToNewInstanceMap, TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0> > & InOldToNewClassMap, AActor * OldActor, TMap<FSoftObjectPath,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<FSoftObjectPath,UObject *,0> > & ReinstancedObjectsWeakReferenceMap, TMap<UObject *,FActorAttachmentData,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,FActorAttachmentData,0> > & ActorAttachmentData, TArray<FActorReplacementHelper,FDefaultAllocator> & ReplacementActors, bool bPreserveRootComponent, bool & bSelectionChanged) Line 1816 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReplaceInstancesOfClass_Inner(TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0> > & InOldToNewClassMap, UObject * InOriginalCDO, TSet<UObject *,DefaultKeyFuncs<UObject *,0>,FDefaultSetAllocator> * ObjectsThatShouldUseOldStuff, bool bClassObjectReplaced, bool bPreserveRootComponent, bool bArchetypesAreUpToDate) Line 2013 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReplaceInstancesOfClass(UClass * OldClass, UClass * NewClass, UObject * OriginalCDO, TSet<UObject *,DefaultKeyFuncs<UObject *,0>,FDefaultSetAllocator> * ObjectsThatShouldUseOldStuff, bool bClassObjectReplaced, bool bPreserveRootComponent) Line 1460 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReinstanceInner(bool bForceAlwaysReinstance) Line 660 C++
UE4Editor-UnrealEd.dll!FBlueprintCompileReinstancer::ReinstanceObjects(bool bForceAlwaysReinstance) Line 904 C++
UE4Editor-USharp.dll!Export_SharpHotReloadUtils_ReinstanceClass(FSharpHotReloadClassReinstancer * Reinstancer) Line 45 C++
[Managed to Native Transition]
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.ManagedUnrealTypes.BuildTypes() Line 907 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.ManagedUnrealTypes.Load() Line 63 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.Native.NativeFunctions.OnNativeFunctionsRegistered() Line 189 C#
UnrealEngine.Runtime.dll!UnrealEngine.Runtime.Native.NativeFunctions.RegisterFunctions(System.IntPtr registerFunctionsAddr) Line 99 C#
UnrealEngine.Runtime.dll!UnrealEngine.EntryPoint.DllMain(string arg) Line 70 C#
[Native to Managed Transition]
[Managed to Native Transition]
Loader.dll!UnrealEngine.AssemblyLoader.Load() Line 475 C#
[AppDomain (DefaultDomain�, #1) -> AppDomain (Domain30654212 4�, #6)]
Loader.dll!UnrealEngine.EntryPoint.ReloadAppDomain() Line 249 C#
Loader.dll!UnrealEngine.EntryPoint.ReloadAppDomain.AnonymousMethod__0() Line 195 C#
Loader.dll!UnrealEngine.GameThreadHelper.Tick(float deltaTime) Line 672 C#
[Native to Managed Transition]
UE4Editor-USharp.dll!FTickerDelegateWrapper::Tick(float DeltaTime) Line 9 C++
UE4Editor-Core.dll!FTicker::Tick(float DeltaTime) Line 98 C++
UE4Editor.exe!FEngineLoop::Tick() Line 3669 C++
UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 166 C++
UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 209 C++
UE4Editor.exe!__scrt_common_main_seh() Line 283 C++
kernel32.dll!00000000778b59cd() Unknown
ntdll.dll!0000000077a1385d() Unknown