Unable to set editor_property from spawned blueprint object in python

Hi,
I am creating a bunch of actors from a python script, assing them a random navigable location and set a editor property, and this fails.

import unreal
import json
import os
import random

# Path to the source Blueprint
source_bp_path = "/Game/ThirdPerson/AI/Enemy_Character.Enemy_Character"

# Load JSON entries
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, "test_content", "content.json")

with open(file_path, "r", encoding="utf-8") as f:
    entries = json.load(f)

# Destination folder in Content Browser
destination_folder = "/Game/ThirdPerson/AI/Generated_Characters"

# Ensure the folder exists
if not unreal.EditorAssetLibrary.does_directory_exist(destination_folder):
    unreal.EditorAssetLibrary.make_directory(destination_folder)

# Get world and nav system
world = unreal.EditorLevelLibrary.get_editor_world()
nav_sys = unreal.NavigationSystemV1.get_navigation_system(world)

for entry in entries:
    asset_name = f"{entry['id']}_BP"
    asset_path = f"{destination_folder}/{asset_name}"

    # Delete if exists
    if unreal.EditorAssetLibrary.does_asset_exist(asset_path):
        unreal.EditorAssetLibrary.delete_asset(asset_path)

    # Duplicate the asset
    duplicated = unreal.EditorAssetLibrary.duplicate_asset(source_bp_path, asset_path)

    if duplicated:
        unreal.EditorAssetLibrary.save_asset(asset_path, only_if_is_dirty=False)
        print(f"Saved duplicated Blueprint: {asset_path}")
    else:
        print(f"Failed to create asset: {asset_path}")
        continue

    # Load class from duplicated Blueprint
    generated_class_path = f"{asset_path}.{asset_name}"
    bp_class = unreal.EditorAssetLibrary.load_blueprint_class(generated_class_path)

    if not bp_class:
        print(f"Failed to load Blueprint class: {generated_class_path}")
        continue

    # Close to the players launch area
    origin = unreal.Vector(900, 1110, 92)
    radius = 10000
    nav_location = nav_sys.get_random_reachable_point_in_radius(world, origin, radius)

    if not nav_location:
        print(f"No valid navigable location found for {entry['id']}")
        continue
    
    print(f"Location {nav_location}")
    location = nav_location
    rotation = unreal.Rotator(0, random.uniform(0, 360), 0)

    # Spawn actor
    actor = unreal.EditorLevelLibrary.spawn_actor_from_class(bp_class, location, rotation)

    if "Prompt" in dir(actor):
        print("Prompt is available")
    else:
        print("Prompt NOT found")

    components = actor.get_components_by_class(unreal.ActorComponent)
    for comp in components:
        print(f"Component: {comp.get_name()} - {comp.get_class().get_name()}")
        
    if actor:
        # Set the 'Prompt' property
        try:
            actor.set_editor_property("Prompt", "hello world")
            print(f"Spawned {entry['id']} at {location} with Prompt set")
        except Exception as e:
            print(f"Spawned {entry['id']} but failed to set Prompt: {e}")
    else:
        print(f"Failed to spawn {entry['id']} in level")

My content.json looks like this

[
  {
    "id": "prompt1_001",
    "title": "Welcome",
    "description": "Welcome to the game!"
  },
  {
    "id": "prompt1_002",
    "title": "Goodbye",
    "description": "Thanks for playing!"
  },
  {
    "id": "prompt1_003",
    "title": "Goodbye",
    "description": "Thanks for playing!"
  },
  {
    "id": "prompt1_004",
    "title": "Goodbye",
    "description": "Thanks for playing!"
  },
  {
    "id": "prompt1_005",
    "title": "Goodbye",
    "description": "Thanks for playing!"
  },
  {
    "id": "prompt1_006",
    "title": "Hello",
    "description": "Thanks for playing!"
  }
]

My Blueprint class has the ‘Prompt’ property

However it never seems to find the property ‘Prompt’. I always see “Prompt NOT found”

What am I doing wrong? Any help is greatly appreciated.

Best,
Stan

Ok, I got it hours later, it seems that the default value winw, so one needs to override the default value.

    # need to be set before spawning, otherwise
    # the value will be reset to the default in
    # the construction phase
    cdo = unreal.get_default_object(bp_class)
    cdo.set_editor_property("Prompt", "Hello Word Again")

I assume using data object that encapsulate the data will not lead to the same behaviour.

Full Script:

import unreal
import json
import os
import random
  
# Load JSON entries
file_path = os.path.join(os.path.dirname(__file__), "test_content", "content.json")
  
with open(file_path, "r", encoding="utf-8") as f:
    entries = json.load(f)
  
# Path to the source Blueprint
source_bp_path = "/Game/ThirdPerson/AI/Enemy_Character.Enemy_Character"
  
# Destination for generated assets
destination_folder = "/Game/ThirdPerson/AI/Generated_Characters"
  
# Ensure the folder exists
if not unreal.EditorAssetLibrary.does_directory_exist(destination_folder):
    unreal.EditorAssetLibrary.make_directory(destination_folder)
  
# Get world and nav system, used to spawn at location down the line
world = unreal.EditorLevelLibrary.get_editor_world()
nav_sys = unreal.NavigationSystemV1.get_navigation_system(world)
  
  
for entry in entries:
    asset_name = f"{entry['id']}_BP"
    asset_path = f"{destination_folder}/{asset_name}"
  
    asset = unreal.EditorAssetLibrary.load_asset(asset_path)
    if not asset:
        asset = unreal.EditorAssetLibrary.duplicate_asset(source_bp_path, asset_path)
        
    # Load class from duplicated Blueprint
    generated_class_path = f"{asset_path}.{asset_name}"
    bp_class = unreal.EditorAssetLibrary.load_blueprint_class(generated_class_path)
  
    # need to be set before spawning, otherwise
    # the value will be reset to the default in
    # the construction phase
    cdo = unreal.get_default_object(bp_class)
    cdo.set_editor_property("Prompt", "Hello Word Again")
    
    # Close to the players launch area for now
    origin = unreal.Vector(900, 1110, 92)
    radius = 10000
    location = nav_sys.get_random_reachable_point_in_radius(world, origin, radius)
  
    if not location:
        print(f"No valid navigable location found for {entry['id']}")
        quit() #fail early
    
    actor = unreal.EditorLevelLibrary.spawn_actor_from_class(bp_class, location, rotation = unreal.Rotator(0, random.uniform(0, 360), 0) )
    
    unreal.EditorAssetLibrary.save_loaded_asset(asset)