Files
spacegame/Plugins/UnrealMCPython/Content/Python/UnrealMCPython/tests/test_static_mesh.py
Joshua Deville 496320cc8c Add empty test level and Unreal MCP tooling
- L_TestFlight: empty, zero-gravity level for Phase 0 flight testing,
  set as editor/game default map.
- Enable UnrealMCPython + Python Editor Script Plugin, third-party
  MCP plugin (GenOrca/unreal-mcp v2.2.0) giving direct editor control
  (actors, blueprints, levels, materials, etc.) alongside Epic's
  built-in Unreal MCP plugin.
- Vendor the mcp-server Python source used to bridge to the plugin.
- .mcp.json intentionally gitignored (machine-specific absolute paths).
2026-07-08 14:56:57 -04:00

131 lines
5.6 KiB
Python

import unreal
from UnrealMCPython.tests.base import MCPTestCase, TEST_ROOT
_SRC = "/Engine/BasicShapes/Cube"
_DEFAULT_MAT = "/Engine/BasicShapes/BasicShapeMaterial"
class TestStaticMeshActions(MCPTestCase):
def test_get_static_mesh_info(self):
r = self.call("static_mesh_actions", "ue_get_static_mesh_info", asset_path=_SRC)
self.assertSuccess(r)
self.assertGreaterEqual(r["num_lods"], 1)
self.assertGreater(r["num_triangles_lod0"], 0)
self.assertGreater(r["num_vertices_lod0"], 0)
def test_get_static_mesh_info_invalid(self):
r = self.call("static_mesh_actions", "ue_get_static_mesh_info",
asset_path="/Game/DoesNotExist_XYZ")
self.assertFalse(r.get("success"))
def test_list_materials(self):
r = self.call("static_mesh_actions", "ue_list_static_mesh_materials", asset_path=_SRC)
self.assertSuccess(r)
self.assertGreaterEqual(r["num_materials"], 1)
def test_get_collision_info(self):
r = self.call("static_mesh_actions", "ue_get_collision_info", asset_path=_SRC)
self.assertSuccess(r)
self.assertIn("simple_collision_count", r)
def test_set_material(self):
self.ensure_test_dir()
dst = f"{TEST_ROOT}/MCP_SMCopy"
self.delete_asset(dst)
unreal.EditorAssetLibrary.duplicate_asset(_SRC, dst)
try:
r = self.call("static_mesh_actions", "ue_set_static_mesh_material",
asset_path=dst, slot_index=0, material_path=_DEFAULT_MAT)
self.assertSuccess(r)
finally:
self.delete_asset(dst)
def test_add_simple_collision(self):
self.ensure_test_dir()
dst = f"{TEST_ROOT}/MCP_SMCol"
self.delete_asset(dst)
unreal.EditorAssetLibrary.duplicate_asset(_SRC, dst)
try:
before = self.call("static_mesh_actions", "ue_get_collision_info",
asset_path=dst)["simple_collision_count"]
r = self.call("static_mesh_actions", "ue_add_simple_collision",
asset_path=dst, shape="SPHERE")
self.assertSuccess(r)
self.assertGreater(r["simple_collision_count"], before)
finally:
self.delete_asset(dst)
def test_add_simple_collision_bad_shape(self):
r = self.call("static_mesh_actions", "ue_add_simple_collision",
asset_path=_SRC, shape="NOTASHAPE")
self.assertFalse(r.get("success"))
# ── LODs ─────────────────────────────────────────────────────────────────────
def _dup_mesh(self, name):
self.ensure_test_dir()
dst = f"{TEST_ROOT}/{name}"
self.delete_asset(dst)
unreal.EditorAssetLibrary.duplicate_asset(_SRC, dst)
return dst
def test_set_and_remove_lods(self):
dst = self._dup_mesh("MCP_SMLod")
try:
r = self.call("static_mesh_actions", "ue_set_lods", asset_path=dst,
lod_settings=[{"percent_triangles": 1.0, "screen_size": 1.0},
{"percent_triangles": 0.5, "screen_size": 0.5}])
self.assertSuccess(r)
self.assertEqual(r["lod_count"], 2)
r = self.call("static_mesh_actions", "ue_get_lod_screen_sizes", asset_path=dst)
self.assertSuccess(r)
self.assertEqual(len(r["screen_sizes"]), 2)
r = self.call("static_mesh_actions", "ue_remove_lods", asset_path=dst)
self.assertSuccess(r)
self.assertEqual(r["lod_count"], 1)
finally:
self.delete_asset(dst)
def test_set_lods_missing(self):
r = self.call("static_mesh_actions", "ue_set_lods", asset_path=_SRC)
self.assertFalse(r.get("success"))
def test_set_lod_from_static_mesh(self):
dst = self._dup_mesh("MCP_SMLodCopy")
try:
r = self.call("static_mesh_actions", "ue_set_lod_from_static_mesh",
asset_path=dst, lod_index=1,
source_path="/Engine/BasicShapes/Sphere", source_lod_index=0)
self.assertSuccess(r)
self.assertEqual(r["lod_count"], 2)
finally:
self.delete_asset(dst)
# ── convex / collision management ───────────────────────────────────────────
def test_convex_and_remove_collisions(self):
dst = self._dup_mesh("MCP_SMConvex")
try:
r = self.call("static_mesh_actions", "ue_set_convex_collision",
asset_path=dst, hull_count=2, max_hull_verts=16, hull_precision=100000)
self.assertSuccess(r)
self.assertGreaterEqual(r["convex_collision_count"], 1)
r = self.call("static_mesh_actions", "ue_remove_collisions", asset_path=dst)
self.assertSuccess(r)
self.assertEqual(r["convex_collision_count"], 0)
finally:
self.delete_asset(dst)
def test_set_lod_for_collision(self):
dst = self._dup_mesh("MCP_SMLodCol")
try:
r = self.call("static_mesh_actions", "ue_set_lod_for_collision",
asset_path=dst, lod_index=0)
self.assertSuccess(r)
r = self.call("static_mesh_actions", "ue_set_lod_for_collision",
asset_path=dst, lod_index=99)
self.assertFalse(r.get("success"))
finally:
self.delete_asset(dst)