186 lines
6.9 KiB
Python
186 lines
6.9 KiB
Python
"""
|
|
Landscape Tools for Unreal MCP.
|
|
|
|
This module provides tools for managing landscapes in Unreal Engine through the Landscape Editor module.
|
|
Following Epic's official structure: Editor/Landscape module patterns.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Dict, List, Any, Optional
|
|
from mcp.server.fastmcp import FastMCP, Context
|
|
|
|
# Get logger
|
|
logger = logging.getLogger("UnrealMCP")
|
|
|
|
def register_landscape_tools(mcp: FastMCP):
|
|
"""Register landscape tools with the MCP server."""
|
|
|
|
@mcp.tool()
|
|
def create_landscape(ctx: Context,
|
|
size_x: int = 127,
|
|
size_y: int = 127,
|
|
sections_per_component: int = 1,
|
|
quads_per_section: int = 63,
|
|
location_x: float = 0.0,
|
|
location_y: float = 0.0,
|
|
location_z: float = 0.0) -> Dict[str, Any]:
|
|
"""Create a landscape in the current level.
|
|
|
|
Args:
|
|
size_x: Landscape size in X direction (default: 127)
|
|
size_y: Landscape size in Y direction (default: 127)
|
|
sections_per_component: Number of sections per component (default: 1)
|
|
quads_per_section: Number of quads per section (default: 63)
|
|
location_x: X location of the landscape (default: 0.0)
|
|
location_y: Y location of the landscape (default: 0.0)
|
|
location_z: Z location of the landscape (default: 0.0)
|
|
|
|
Returns:
|
|
Dictionary containing the landscape creation result
|
|
|
|
Example:
|
|
create_landscape(size_x=255, size_y=255, location_z=100.0)
|
|
"""
|
|
from unreal_mcp_server import get_unreal_connection
|
|
|
|
try:
|
|
unreal = get_unreal_connection()
|
|
if not unreal:
|
|
logger.warning("Failed to connect to Unreal Engine")
|
|
return {"error": "Failed to connect to Unreal Engine"}
|
|
|
|
response = unreal.send_command("create_landscape", {
|
|
"size_x": size_x,
|
|
"size_y": size_y,
|
|
"sections_per_component": sections_per_component,
|
|
"quads_per_section": quads_per_section,
|
|
"location": {
|
|
"x": location_x,
|
|
"y": location_y,
|
|
"z": location_z
|
|
}
|
|
})
|
|
|
|
if not response:
|
|
logger.warning("No response from Unreal Engine")
|
|
return {"error": "No response from Unreal Engine"}
|
|
|
|
logger.info(f"Created landscape with size {size_x}x{size_y}")
|
|
return response
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error creating landscape: {e}")
|
|
return {"error": f"Error creating landscape: {str(e)}"}
|
|
|
|
@mcp.tool()
|
|
def modify_landscape(ctx: Context, modification_type: str = "sculpt") -> Dict[str, Any]:
|
|
"""Modify the landscape heightmap.
|
|
|
|
Args:
|
|
modification_type: Type of modification to perform (default: "sculpt")
|
|
|
|
Returns:
|
|
Dictionary containing the landscape modification result
|
|
|
|
Example:
|
|
modify_landscape("sculpt")
|
|
"""
|
|
from unreal_mcp_server import get_unreal_connection
|
|
|
|
try:
|
|
unreal = get_unreal_connection()
|
|
if not unreal:
|
|
logger.warning("Failed to connect to Unreal Engine")
|
|
return {"error": "Failed to connect to Unreal Engine"}
|
|
|
|
response = unreal.send_command("modify_landscape", {
|
|
"modification_type": modification_type
|
|
})
|
|
|
|
if not response:
|
|
logger.warning("No response from Unreal Engine")
|
|
return {"error": "No response from Unreal Engine"}
|
|
|
|
logger.info(f"Modified landscape with type: {modification_type}")
|
|
return response
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error modifying landscape: {e}")
|
|
return {"error": f"Error modifying landscape: {str(e)}"}
|
|
|
|
@mcp.tool()
|
|
def paint_landscape_layer(ctx: Context, layer_name: str) -> Dict[str, Any]:
|
|
"""Paint a landscape material layer.
|
|
|
|
Args:
|
|
layer_name: Name of the landscape layer to paint
|
|
|
|
Returns:
|
|
Dictionary containing the landscape painting result
|
|
|
|
Example:
|
|
paint_landscape_layer("Grass")
|
|
"""
|
|
from unreal_mcp_server import get_unreal_connection
|
|
|
|
try:
|
|
unreal = get_unreal_connection()
|
|
if not unreal:
|
|
logger.warning("Failed to connect to Unreal Engine")
|
|
return {"error": "Failed to connect to Unreal Engine"}
|
|
|
|
response = unreal.send_command("paint_landscape_layer", {
|
|
"layer_name": layer_name
|
|
})
|
|
|
|
if not response:
|
|
logger.warning("No response from Unreal Engine")
|
|
return {"error": "No response from Unreal Engine"}
|
|
|
|
logger.info(f"Painted landscape layer: {layer_name}")
|
|
return response
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error painting landscape layer: {e}")
|
|
return {"error": f"Error painting landscape layer: {str(e)}"}
|
|
|
|
@mcp.tool()
|
|
def get_landscape_info(ctx: Context) -> List[Dict[str, Any]]:
|
|
"""Get information about all landscapes in the current level.
|
|
|
|
Returns:
|
|
List of dictionaries containing landscape information
|
|
|
|
Example:
|
|
get_landscape_info()
|
|
"""
|
|
from unreal_mcp_server import get_unreal_connection
|
|
|
|
try:
|
|
unreal = get_unreal_connection()
|
|
if not unreal:
|
|
logger.warning("Failed to connect to Unreal Engine")
|
|
return []
|
|
|
|
response = unreal.send_command("get_landscape_info", {})
|
|
|
|
if not response:
|
|
logger.warning("No response from Unreal Engine")
|
|
return []
|
|
|
|
# Check response format
|
|
if "result" in response and "landscapes" in response["result"]:
|
|
landscapes = response["result"]["landscapes"]
|
|
logger.info(f"Found {len(landscapes)} landscapes in level")
|
|
return landscapes
|
|
elif "landscapes" in response:
|
|
landscapes = response["landscapes"]
|
|
logger.info(f"Found {len(landscapes)} landscapes in level")
|
|
return landscapes
|
|
|
|
logger.warning(f"Unexpected response format: {response}")
|
|
return []
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting landscape info: {e}")
|
|
return [] |