editor_update_object
Modify existing objects or actors in Unreal Engine by updating their position, rotation, scale, materials, or name to adjust scene composition.
Instructions
Update an existing object/actor in the world
Example output: {'success': true, 'actor_name': 'StaticMeshActor_1', 'actor_label': 'UpdatedCube', 'class': 'StaticMeshActor', 'location': {'x': 150.0, 'y': 200.0, 'z': 50.0}, 'rotation': {'pitch': 0.0, 'yaw': 90.0, 'roll': 0.0}, 'scale': {'x': 2.0, 'y': 2.0, 'z': 2.0}}
Returns updated actor details with new transform values.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| actor_name | Yes | Name or label of the actor to update | |
| location | No | New world position coordinates | |
| rotation | No | New rotation in degrees | |
| scale | No | New scale multipliers | |
| properties | No | Additional actor properties to update. For StaticMeshActor: use 'StaticMesh' for mesh path, 'Material' for single material path, or 'Materials' for array of material paths. Example: {"StaticMesh": "/Game/Meshes/Cube", "Material": "/Game/Materials/M_Basic"} | |
| new_name | No | New name/label for the actor |
Implementation Reference
- Core handler function that finds the target actor in the editor world by name or label, then updates its location, rotation, scale, properties, and optionally renames it. Returns success status and updated actor details.def update_object( actor_name: str, location: Optional[Dict[str, float]] = None, rotation: Optional[Dict[str, float]] = None, scale: Optional[Dict[str, float]] = None, properties: Optional[Dict[str, Any]] = None, new_name: Optional[str] = None, ) -> Dict[str, Any]: try: world = unreal.get_editor_subsystem( unreal.UnrealEditorSubsystem ).get_editor_world() if not world: return {"error": "No world loaded"} all_actors = unreal.get_editor_subsystem( unreal.EditorActorSubsystem ).get_all_level_actors() target_actor = None for actor in all_actors: if actor.get_name() == actor_name or actor.get_actor_label() == actor_name: target_actor = actor break if not target_actor: return {"error": f"Actor not found: {actor_name}"} if location: new_location = unreal.Vector( x=location.get("x", target_actor.get_actor_location().x), y=location.get("y", target_actor.get_actor_location().y), z=location.get("z", target_actor.get_actor_location().z), ) target_actor.set_actor_location(new_location, False, False) if rotation: new_rotation = unreal.Rotator( pitch=rotation.get("pitch", target_actor.get_actor_rotation().pitch), yaw=rotation.get("yaw", target_actor.get_actor_rotation().yaw), roll=rotation.get("roll", target_actor.get_actor_rotation().roll), ) target_actor.set_actor_rotation(new_rotation, False) if scale: new_scale = unreal.Vector( x=scale.get("x", target_actor.get_actor_scale3d().x), y=scale.get("y", target_actor.get_actor_scale3d().y), z=scale.get("z", target_actor.get_actor_scale3d().z), ) target_actor.set_actor_scale3d(new_scale) if new_name: target_actor.set_actor_label(new_name) if properties: for prop_name, prop_value in properties.items(): try: if hasattr(target_actor, prop_name): setattr(target_actor, prop_name, prop_value) except Exception as e: continue return { "success": True, "actor_name": target_actor.get_name(), "actor_label": target_actor.get_actor_label(), "class": target_actor.get_class().get_name(), "location": { "x": target_actor.get_actor_location().x, "y": target_actor.get_actor_location().y, "z": target_actor.get_actor_location().z, }, "rotation": { "pitch": target_actor.get_actor_rotation().pitch, "yaw": target_actor.get_actor_rotation().yaw, "roll": target_actor.get_actor_rotation().roll, }, "scale": { "x": target_actor.get_actor_scale3d().x, "y": target_actor.get_actor_scale3d().y, "z": target_actor.get_actor_scale3d().z, }, } except Exception as e: return {"error": f"Failed to update object: {str(e)}"}
- server/editor/tools.ts:55-71 (helper)Helper function that loads the ue_update_object.py script as a template and substitutes the input parameters (JSON stringified where needed) to generate the executable Python code.export const UEUpdateObject = ( actor_name: string, location?: { x: number; y: number; z: number }, rotation?: { pitch: number; yaw: number; roll: number }, scale?: { x: number; y: number; z: number }, properties?: Record<string, any>, new_name?: string, ) => { return Template(read("./scripts/ue_update_object.py"), { actor_name, location: location ? JSON.stringify(location) : "null", rotation: rotation ? JSON.stringify(rotation) : "null", scale: scale ? JSON.stringify(scale) : "null", properties: properties ? JSON.stringify(properties) : "null", new_name: new_name || "null", }) }
- server/index.ts:387-437 (registration)Registers the 'editor_update_object' tool with the MCP server, including description and the thin async handler that invokes tryRunCommand on the UEUpdateObject helper.server.tool( "editor_update_object", "Update an existing object/actor in the world\n\nExample output: {'success': true, 'actor_name': 'StaticMeshActor_1', 'actor_label': 'UpdatedCube', 'class': 'StaticMeshActor', 'location': {'x': 150.0, 'y': 200.0, 'z': 50.0}, 'rotation': {'pitch': 0.0, 'yaw': 90.0, 'roll': 0.0}, 'scale': {'x': 2.0, 'y': 2.0, 'z': 2.0}}\n\nReturns updated actor details with new transform values.", { actor_name: z.string().describe("Name or label of the actor to update"), location: z .object({ x: z.number(), y: z.number(), z: z.number(), }) .optional() .describe("New world position coordinates"), rotation: z .object({ pitch: z.number(), yaw: z.number(), roll: z.number(), }) .optional() .describe("New rotation in degrees"), scale: z .object({ x: z.number(), y: z.number(), z: z.number(), }) .optional() .describe("New scale multipliers"), properties: z .record(z.any()) .optional() .describe( 'Additional actor properties to update. For StaticMeshActor: use \'StaticMesh\' for mesh path, \'Material\' for single material path, or \'Materials\' for array of material paths. Example: {"StaticMesh": "/Game/Meshes/Cube", "Material": "/Game/Materials/M_Basic"}', ), new_name: z.string().optional().describe("New name/label for the actor"), }, async ({ actor_name, location, rotation, scale, properties, new_name }) => { const result = await tryRunCommand( editorTools.UEUpdateObject(actor_name, location, rotation, scale, properties, new_name), ) return { content: [ { type: "text", text: result, }, ], } }, )
- server/index.ts:390-423 (schema)Zod schema for input validation: requires actor_name; optional location, rotation, scale as objects with x/y/z, properties as record, new_name string.{ actor_name: z.string().describe("Name or label of the actor to update"), location: z .object({ x: z.number(), y: z.number(), z: z.number(), }) .optional() .describe("New world position coordinates"), rotation: z .object({ pitch: z.number(), yaw: z.number(), roll: z.number(), }) .optional() .describe("New rotation in degrees"), scale: z .object({ x: z.number(), y: z.number(), z: z.number(), }) .optional() .describe("New scale multipliers"), properties: z .record(z.any()) .optional() .describe( 'Additional actor properties to update. For StaticMeshActor: use \'StaticMesh\' for mesh path, \'Material\' for single material path, or \'Materials\' for array of material paths. Example: {"StaticMesh": "/Game/Meshes/Cube", "Material": "/Game/Materials/M_Basic"}', ), new_name: z.string().optional().describe("New name/label for the actor"), },