Add Ground Zero natural environment pass

This commit is contained in:
2026-05-16 02:18:46 -07:00
parent a7292bbae1
commit 25ffbfc564
14 changed files with 355 additions and 12 deletions
+144 -6
View File
@@ -22,6 +22,57 @@ FOLIAGE_MESHES = {
"shrub": "/Game/LevelPrototyping/Meshes/SM_Cube",
"grass": "/Game/LevelPrototyping/Meshes/SM_Cylinder",
}
MATERIAL_FOLDER = "/Game/Agrarian/Materials"
ENVIRONMENT_MATERIALS = {
"terrain": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Terrain_CoastalScrub",
"color": unreal.LinearColor(0.28, 0.24, 0.16, 1.0),
"roughness": 0.92,
},
"tree": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Tree_CoastalOak",
"color": unreal.LinearColor(0.18, 0.31, 0.16, 1.0),
"roughness": 0.88,
},
"shrub": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Shrub_CoyoteBrush",
"color": unreal.LinearColor(0.31, 0.39, 0.20, 1.0),
"roughness": 0.9,
},
"grass": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Grass_DryCoastal",
"color": unreal.LinearColor(0.47, 0.42, 0.23, 1.0),
"roughness": 0.95,
},
"wood_resource": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Wood_Resource",
"color": unreal.LinearColor(0.26, 0.16, 0.08, 1.0),
"roughness": 0.86,
},
"fiber_resource": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Fiber_Resource",
"color": unreal.LinearColor(0.55, 0.49, 0.28, 1.0),
"roughness": 0.93,
},
"stone_resource": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Stone_Sandstone",
"color": unreal.LinearColor(0.43, 0.40, 0.35, 1.0),
"roughness": 0.97,
},
"fresh_water": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_FreshWater",
"color": unreal.LinearColor(0.08, 0.28, 0.38, 1.0),
"roughness": 0.35,
},
}
RESOURCE_MATERIAL_BY_LABEL_PREFIX = {
"AGR_GZ_Wood": "wood_resource",
"AGR_GZ_Fiber": "fiber_resource",
"AGR_GZ_Stone": "stone_resource",
"AGR_DemoWoodResource": "wood_resource",
"AGR_DemoFiberResource": "fiber_resource",
"AGR_GZ_FreshWaterSource": "fresh_water",
}
DEMO_ACTORS = [
@@ -245,6 +296,75 @@ def load_required_asset(path):
return asset
def ensure_environment_materials():
if not unreal.EditorAssetLibrary.does_directory_exist(MATERIAL_FOLDER):
unreal.EditorAssetLibrary.make_directory(MATERIAL_FOLDER)
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
created_or_loaded = {}
for key, spec in ENVIRONMENT_MATERIALS.items():
material = unreal.EditorAssetLibrary.load_asset(spec["path"])
if not material:
asset_name = spec["path"].rsplit("/", 1)[-1]
material = asset_tools.create_asset(asset_name, MATERIAL_FOLDER, unreal.Material, unreal.MaterialFactoryNew())
if not material:
raise RuntimeError(f"Could not create material: {spec['path']}")
base_color = unreal.MaterialEditingLibrary.create_material_expression(
material, unreal.MaterialExpressionConstant3Vector, -420, -120
)
base_color.set_editor_property("constant", spec["color"])
unreal.MaterialEditingLibrary.connect_material_property(
base_color, "", unreal.MaterialProperty.MP_BASE_COLOR
)
roughness = unreal.MaterialEditingLibrary.create_material_expression(
material, unreal.MaterialExpressionConstant, -420, 80
)
roughness.set_editor_property("r", spec["roughness"])
unreal.MaterialEditingLibrary.connect_material_property(
roughness, "", unreal.MaterialProperty.MP_ROUGHNESS
)
unreal.MaterialEditingLibrary.recompile_material(material)
unreal.EditorAssetLibrary.save_asset(spec["path"])
unreal.log(f"Created Ground Zero environment material: {spec['path']}")
created_or_loaded[key] = material
return created_or_loaded
def apply_material_to_actor_meshes(actor, material):
applied_count = 0
for component in actor.get_components_by_class(unreal.StaticMeshComponent):
slot_count = component.get_num_materials()
if slot_count == 0:
component.set_material(0, material)
applied_count += 1
continue
for slot_index in range(slot_count):
component.set_material(slot_index, material)
applied_count += 1
return applied_count
def material_key_for_actor_label(label):
for prefix, material_key in RESOURCE_MATERIAL_BY_LABEL_PREFIX.items():
if label.startswith(prefix):
return material_key
return None
def apply_landscape_material(material):
applied = 0
for actor in unreal.EditorLevelLibrary.get_all_level_actors():
if isinstance(actor, unreal.Landscape):
actor.set_editor_property("landscape_material", material)
applied += 1
unreal.log(f"Applied Ground Zero terrain material to {applied} landscape actor(s).")
return applied
def load_heightmap():
raw = HEIGHTMAP_PATH.read_bytes()
expected_bytes = LANDSCAPE_SIZE * LANDSCAPE_SIZE * 2
@@ -295,6 +415,18 @@ def configure_foliage_meshes(foliage_actor):
component.set_editor_property("static_mesh", mesh)
def apply_foliage_materials(foliage_actor, materials):
component_materials = {
"tree_instances": materials["tree"],
"shrub_instances": materials["shrub"],
"grass_instances": materials["grass"],
}
for property_name, material in component_materials.items():
component = foliage_actor.get_editor_property(property_name)
component.set_material(0, material)
def choose_foliage_points(height_values, zone, reserved_points, existing_points):
rng = random.Random(FOLIAGE_RANDOM_SEED + len(existing_points) + int(zone["count"]))
chosen = []
@@ -325,7 +457,7 @@ def choose_foliage_points(height_values, zone, reserved_points, existing_points)
return chosen
def spawn_foliage_actor(height_values):
def spawn_foliage_actor(height_values, materials):
reserved_points = [
spec["location_xy"]
for spec in DEMO_ACTORS
@@ -343,6 +475,7 @@ def spawn_foliage_actor(height_values):
set_actor_label(foliage_actor, FOLIAGE_LABEL)
configure_foliage_meshes(foliage_actor)
apply_foliage_materials(foliage_actor, materials)
foliage_actor.clear_foliage()
existing_points = []
@@ -375,7 +508,7 @@ def spawn_foliage_actor(height_values):
return foliage_actor
def spawn_demo_actor(spec, height_values):
def spawn_demo_actor(spec, height_values, materials):
location_xy = spec["location_xy"]
z = spec.get("fixed_z")
if z is None:
@@ -395,6 +528,9 @@ def spawn_demo_actor(spec, height_values):
raise RuntimeError(f"Could not spawn {spec['label']}")
set_actor_label(actor, spec["label"])
material_key = material_key_for_actor_label(spec["label"])
if material_key:
apply_material_to_actor_meshes(actor, materials[material_key])
unreal.log(f"Placed {spec['label']} at {actor.get_actor_location()}")
return actor
@@ -410,14 +546,16 @@ def main():
labels.add(FOLIAGE_LABEL)
remove_existing_demo_actors(labels)
materials = ensure_environment_materials()
apply_landscape_material(materials["terrain"])
height_values = load_heightmap()
spawn_foliage_actor(height_values)
spawn_foliage_actor(height_values, materials)
for spec in BIOME_RESOURCE_ACTORS:
spawn_demo_actor(spec, height_values)
spawn_demo_actor(spec, height_values, materials)
for spec in WATER_SOURCE_ACTORS:
spawn_demo_actor(spec, height_values)
spawn_demo_actor(spec, height_values, materials)
for spec in DEMO_ACTORS:
spawn_demo_actor(spec, height_values)
spawn_demo_actor(spec, height_values, materials)
unreal.EditorLevelLibrary.save_current_level()
unreal.log("Ground Zero demo map setup complete.")