editor_tools.py•13.8 kB
#!/usr/bin/env python
"""
Editor Tools for Unreal Engine MCP
Provides tools for interacting with the Unreal Editor, including actor manipulation,
viewport control, and other editor-specific functionality.
"""
import logging
import json
from typing import Dict, Any, List, Optional, Union, Tuple
logger = logging.getLogger("UnrealMCP.EditorTools")
def register_editor_tools(mcp):
"""Register all editor tools with the MCP server."""
@mcp.tool()
def get_actors_in_level() -> Dict[str, Any]:
"""Get a list of all actors in the current level.
Returns:
A dictionary containing the list of actors with their names, types, and locations.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
response = conn.send_command("get_actors_in_level")
return response
@mcp.tool()
def find_actors_by_name(pattern: str) -> Dict[str, Any]:
"""Find actors in the current level by name pattern.
Args:
pattern: A string pattern to match against actor names.
Can use * as a wildcard.
Returns:
A dictionary containing the list of matching actors.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
response = conn.send_command("find_actors_by_name", {"pattern": pattern})
return response
@mcp.tool()
def spawn_actor(
name: str,
type: str = "StaticMeshActor",
location: List[float] = [0, 0, 0],
rotation: List[float] = [0, 0, 0],
scale: List[float] = [1, 1, 1],
properties: Dict[str, Any] = None
) -> Dict[str, Any]:
"""Spawn a new actor in the current level.
Args:
name: The name to give the new actor.
type: The type of actor to spawn (e.g., StaticMeshActor, PointLight).
location: [X, Y, Z] coordinates for the actor's position.
rotation: [Pitch, Yaw, Roll] in degrees for the actor's rotation.
scale: [X, Y, Z] scale factors for the actor.
properties: Optional dictionary of property values to set on the actor.
Returns:
A dictionary containing the result of the operation and the actor details.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"name": name,
"type": type,
"location": location,
"rotation": rotation,
"scale": scale
}
if properties:
params["properties"] = properties
response = conn.send_command("spawn_actor", params)
return response
@mcp.tool()
def delete_actor(name: str) -> Dict[str, Any]:
"""Delete an actor from the current level.
Args:
name: The name of the actor to delete.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
response = conn.send_command("delete_actor", {"name": name})
return response
@mcp.tool()
def set_actor_transform(
name: str,
location: Optional[List[float]] = None,
rotation: Optional[List[float]] = None,
scale: Optional[List[float]] = None
) -> Dict[str, Any]:
"""Set the transform (location, rotation, scale) of an actor.
Args:
name: The name of the actor to modify.
location: Optional [X, Y, Z] coordinates for the actor's position.
rotation: Optional [Pitch, Yaw, Roll] in degrees for the actor's rotation.
scale: Optional [X, Y, Z] scale factors for the actor.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {"name": name}
if location is not None:
params["location"] = location
if rotation is not None:
params["rotation"] = rotation
if scale is not None:
params["scale"] = scale
response = conn.send_command("set_actor_transform", params)
return response
@mcp.tool()
def get_actor_properties(name: str, properties: List[str] = None) -> Dict[str, Any]:
"""Get the properties of an actor.
Args:
name: The name of the actor.
properties: Optional list of specific property names to retrieve.
If None, all properties will be returned.
Returns:
A dictionary containing the actor's properties.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {"name": name}
if properties:
params["properties"] = properties
response = conn.send_command("get_actor_properties", params)
return response
@mcp.tool()
def set_actor_property(
name: str,
property_name: str,
property_value: Any
) -> Dict[str, Any]:
"""Set a property on an actor.
Args:
name: The name of the actor.
property_name: The name of the property to set.
property_value: The value to set for the property.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"name": name,
"property": property_name,
"value": property_value
}
response = conn.send_command("set_actor_property", params)
return response
@mcp.tool()
def focus_viewport(
target: Optional[str] = None,
location: Optional[List[float]] = None,
distance: float = 500.0,
orientation: Optional[List[float]] = None
) -> Dict[str, Any]:
"""Focus the viewport camera on a target actor or location.
Args:
target: The name of the actor to focus on. If provided, location is ignored.
location: [X, Y, Z] coordinates to focus on if target is not provided.
distance: Distance from the target or location.
orientation: Optional [Pitch, Yaw, Roll] in degrees for the camera orientation.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {"distance": distance}
if target:
params["target"] = target
elif location:
params["location"] = location
else:
return {"status": "error", "error": "Either target or location must be provided"}
if orientation:
params["orientation"] = orientation
response = conn.send_command("focus_viewport", params)
return response
@mcp.tool()
def take_screenshot(
filename: str,
show_ui: bool = False,
resolution: List[int] = [1920, 1080]
) -> Dict[str, Any]:
"""Take a screenshot of the current viewport.
Args:
filename: The filename to save the screenshot as (relative to project directory).
show_ui: Whether to include the UI in the screenshot.
resolution: [Width, Height] of the screenshot.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"filename": filename,
"show_ui": show_ui,
"resolution": resolution
}
response = conn.send_command("take_screenshot", params)
return response
@mcp.tool()
def spawn_blueprint_actor(
blueprint_path: str,
actor_name: str,
location: List[float] = [0, 0, 0],
rotation: List[float] = [0, 0, 0],
scale: List[float] = [1, 1, 1],
properties: Dict[str, Any] = None
) -> Dict[str, Any]:
"""Spawn an actor from a Blueprint class.
Args:
blueprint_path: The path to the Blueprint asset (e.g., "/Game/Blueprints/BP_Character").
actor_name: The name to give the spawned actor.
location: [X, Y, Z] coordinates for the actor's position.
rotation: [Pitch, Yaw, Roll] in degrees for the actor's rotation.
scale: [X, Y, Z] scale factors for the actor.
properties: Optional dictionary of property values to set on the actor.
Returns:
A dictionary containing the result of the operation and the actor details.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"blueprint_path": blueprint_path,
"actor_name": actor_name,
"location": location,
"rotation": rotation,
"scale": scale
}
if properties:
params["properties"] = properties
response = conn.send_command("spawn_blueprint_actor", params)
return response
@mcp.tool()
def get_selected_actors() -> Dict[str, Any]:
"""Get a list of currently selected actors in the editor.
Returns:
A dictionary containing the list of selected actors.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
response = conn.send_command("get_selected_actors")
return response
@mcp.tool()
def select_actor(name: str, add_to_selection: bool = False) -> Dict[str, Any]:
"""Select an actor in the editor.
Args:
name: The name of the actor to select.
add_to_selection: If True, add to current selection. If False, clear selection first.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"name": name,
"add_to_selection": add_to_selection
}
response = conn.send_command("select_actor", params)
return response
@mcp.tool()
def clear_selection() -> Dict[str, Any]:
"""Clear the current actor selection in the editor.
Returns:
A dictionary containing the result of the operation.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
response = conn.send_command("clear_selection")
return response
@mcp.tool()
def duplicate_actor(
name: str,
new_name: str,
offset: List[float] = [100, 0, 0]
) -> Dict[str, Any]:
"""Duplicate an existing actor.
Args:
name: The name of the actor to duplicate.
new_name: The name to give the duplicated actor.
offset: [X, Y, Z] offset to apply to the duplicated actor's location.
Returns:
A dictionary containing the result of the operation and the new actor details.
"""
from unreal_mcp_server import get_unreal_connection
conn = get_unreal_connection()
if not conn:
return {"status": "error", "error": "Not connected to Unreal Engine"}
params = {
"name": name,
"new_name": new_name,
"offset": offset
}
response = conn.send_command("duplicate_actor", params)
return response
logger.info("Registered editor tools")