As part of the Python and Editor Scripting Tools, it is possible to programmatically set variables in actor instances of the current level just like when using the Details Panel in the Level Editor. This is done using function set_editor_property() in Python and the BlueprintCallable UKismetSystemLibrary::SetEditorProperty() in Editor Utility Widgets/Blueprints. However, when the current level has "External Actors" enabled, these functions incorrectly fail to set variables of type "Actor Object Reference". The output log displays an error stating that the variable cannot be edited on templates, even though the set was called on an actor instance.

The problem does not happen if "External Actors" is disabled, or when using the direct setters of the variables (when those setters are available) instead of SetEditorProperty().

The faulty behavior can be explained as follows:
1) Variables of type "Actor Object Reference" are automatically marked as CPF_DisableEditOnTemplate, which is correct, since blueprints can be instantiated on any level and there is no guarantee that a default reference would be valid.
2) When external actors are enabled, AActor::IsAsset() returns true, which also makes sense
3) Both SetEditorProperty() functions above perform the check PropertyAccessUtil::IsObjectTemplate() on the owner of the variable being changed. This returns true when AActor::IsAsset() is true (which does not seem to be correct in this case). As a result, the setter functions disallow the change and the call fails.


Steps to Reproduce
  • Open a project, create a new level from the Open World template.
  • Create a BP Actor "BP_Actor". Add a variable "ActorRef" of type "Actor Object Reference" and make it "instance-editable". Compile and save.
  • Create a BP Actor "BP_Other". Save.
  • Add one instance of "BP_Actor" and one of "BP_Other" to the world. Save.
      • Python ***

world = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem).get_editor_world()
actor_class = unreal.EditorAssetLibrary.load_blueprint_class("/Game/BPActor")
other_class = unreal.EditorAssetLibrary.load_blueprint_class("/Game/BPOther")
actor_instance = unreal.GameplayStatics.get_actor_of_class(world, actor_class)
other_instance = unreal.GameplayStatics.get_actor_of_class(world, other_class)
actor_instance.set_editor_property("ActorRef", other_instance)

--> LogPython: Error: Exception: Actor: Property 'ActorRef' for attribute 'ActorRef' on 'BPActor_C' cannot be edited on templates

      • Editor Utility ***
  • Create an Editor Utility Widget, add a button, implement its "On Clicked" event:
  • GetUnrealEditorSubsystem()
  • GetEditorWorld(Target="UnrealEditorSubsystem")
  • GetActorOfClass(ActorClass="BP_Actor")
  • GetActorOfClass(ActorClass="BP_Other")
  • SetEditorProperty(Object="Actor of class BP_Actor", PropertyName="ActorRef", PropertyValue="Actor of class BP_Other")

--> LogScript: Warning: Script Msg: Property 'ActorRef' on '/Temp/Map_Test.Map_Test:PersistentLevel.BPActor_C_UAID_CC96E51C7175DFF601_1144202185' (BPActor_C) cannot be edited on templates
--> Note: If the node SetEditorProperty() is replaced by a direct variable setter, the set succeeds without any problem

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-215347 in the post.

Login to Vote

ComponentUE - World Creation - Worldbuilding Tools
Affects Versions5.3.2
Target Fix5.5
Fix Commit33891702
CreatedMay 19, 2024
ResolvedMay 24, 2024
UpdatedJun 5, 2024
View Jira Issue