Add Ground Zero terrain pipeline and playable assets
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
import unreal
|
||||
|
||||
|
||||
BLUEPRINT_ROOT = "/Game/Agrarian/Blueprints"
|
||||
RESOURCE_FOLDER = f"{BLUEPRINT_ROOT}/Resources"
|
||||
STRUCTURE_FOLDER = f"{BLUEPRINT_ROOT}/Structures"
|
||||
WILDLIFE_FOLDER = f"{BLUEPRINT_ROOT}/Wildlife"
|
||||
|
||||
WOOD_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Wood"
|
||||
FIBER_ITEM_PATH = "/Game/Agrarian/DataAssets/Items/DA_Item_Fiber"
|
||||
|
||||
MESH_CUBE_PATH = "/Game/LevelPrototyping/Meshes/SM_Cube"
|
||||
MESH_CYLINDER_PATH = "/Game/LevelPrototyping/Meshes/SM_Cylinder"
|
||||
|
||||
BLUEPRINTS = [
|
||||
{
|
||||
"asset": "BP_WoodResourceNode",
|
||||
"folder": RESOURCE_FOLDER,
|
||||
"parent": unreal.AgrarianResourceNode,
|
||||
"defaults": {
|
||||
"yield_item_definition": WOOD_ITEM_PATH,
|
||||
"remaining_harvests": 16,
|
||||
"quantity_per_harvest": 2,
|
||||
},
|
||||
"mesh": MESH_CUBE_PATH,
|
||||
"scale": unreal.Vector(1.0, 1.0, 1.5),
|
||||
},
|
||||
{
|
||||
"asset": "BP_FiberResourceNode",
|
||||
"folder": RESOURCE_FOLDER,
|
||||
"parent": unreal.AgrarianResourceNode,
|
||||
"defaults": {
|
||||
"yield_item_definition": FIBER_ITEM_PATH,
|
||||
"remaining_harvests": 10,
|
||||
"quantity_per_harvest": 3,
|
||||
},
|
||||
"mesh": MESH_CYLINDER_PATH,
|
||||
"scale": unreal.Vector(0.8, 0.8, 1.0),
|
||||
},
|
||||
{
|
||||
"asset": "BP_Campfire",
|
||||
"folder": STRUCTURE_FOLDER,
|
||||
"parent": unreal.AgrarianCampfire,
|
||||
"defaults": {
|
||||
"fuel_seconds": 180.0,
|
||||
"warmth_radius": 650.0,
|
||||
"warmth_per_second": 0.03,
|
||||
},
|
||||
"mesh": MESH_CYLINDER_PATH,
|
||||
"scale": unreal.Vector(1.3, 1.3, 0.25),
|
||||
},
|
||||
{
|
||||
"asset": "BP_PrimitiveShelter",
|
||||
"folder": STRUCTURE_FOLDER,
|
||||
"parent": unreal.AgrarianShelterActor,
|
||||
"defaults": {
|
||||
"weather_protection": 0.7,
|
||||
},
|
||||
"mesh": MESH_CUBE_PATH,
|
||||
"scale": unreal.Vector(3.0, 2.0, 1.4),
|
||||
},
|
||||
{
|
||||
"asset": "BP_RabbitWildlife",
|
||||
"folder": WILDLIFE_FOLDER,
|
||||
"parent": unreal.AgrarianWildlifeBase,
|
||||
"defaults": {
|
||||
"wildlife_id": "rabbit",
|
||||
"display_name": "Rabbit",
|
||||
"max_health": 12.0,
|
||||
"health": 12.0,
|
||||
"wander_radius": 900.0,
|
||||
"wander_speed": 160.0,
|
||||
"flee_speed": 520.0,
|
||||
"aggro_radius": 0.0,
|
||||
"flee_radius": 750.0,
|
||||
"decision_interval_seconds": 1.5,
|
||||
"harvest_yields": [
|
||||
{
|
||||
"item_id": "meat",
|
||||
"display_name": "Meat",
|
||||
"quantity": 1,
|
||||
"unit_weight": 0.5,
|
||||
},
|
||||
{
|
||||
"item_id": "hide",
|
||||
"display_name": "Hide",
|
||||
"quantity": 2,
|
||||
"unit_weight": 0.7,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def load_required_asset(path):
|
||||
asset = unreal.EditorAssetLibrary.load_asset(path)
|
||||
if not asset:
|
||||
raise RuntimeError(f"Required asset not found: {path}")
|
||||
return asset
|
||||
|
||||
|
||||
def create_or_load_blueprint(asset_name, folder, parent_class):
|
||||
path = f"{folder}/{asset_name}"
|
||||
existing = unreal.EditorAssetLibrary.load_asset(path)
|
||||
if existing:
|
||||
return existing
|
||||
|
||||
factory = unreal.BlueprintFactory()
|
||||
factory.set_editor_property("parent_class", parent_class)
|
||||
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
|
||||
blueprint = asset_tools.create_asset(asset_name, folder, None, factory)
|
||||
if not blueprint:
|
||||
raise RuntimeError(f"Could not create {path}")
|
||||
return blueprint
|
||||
|
||||
|
||||
def make_stack(data):
|
||||
stack = unreal.AgrarianItemStack()
|
||||
stack.set_editor_property("item_id", data["item_id"])
|
||||
stack.set_editor_property("display_name", data["display_name"])
|
||||
stack.set_editor_property("quantity", data["quantity"])
|
||||
stack.set_editor_property("unit_weight", data["unit_weight"])
|
||||
return stack
|
||||
|
||||
|
||||
def apply_defaults(blueprint, config):
|
||||
blueprint_path = f"{config['folder']}/{config['asset']}"
|
||||
unreal.BlueprintEditorLibrary.compile_blueprint(blueprint)
|
||||
generated_class = unreal.EditorAssetLibrary.load_blueprint_class(blueprint_path)
|
||||
if not generated_class:
|
||||
raise RuntimeError(f"Could not load generated class for {blueprint_path}")
|
||||
|
||||
cdo = unreal.get_default_object(generated_class)
|
||||
|
||||
for property_name, value in config.get("defaults", {}).items():
|
||||
if property_name == "yield_item_definition":
|
||||
value = load_required_asset(value)
|
||||
elif property_name == "harvest_yields":
|
||||
value = [make_stack(stack_data) for stack_data in value]
|
||||
|
||||
cdo.set_editor_property(property_name, value)
|
||||
|
||||
mesh_path = config.get("mesh")
|
||||
if mesh_path:
|
||||
mesh_component = cdo.get_editor_property("mesh")
|
||||
mesh_component.set_editor_property("static_mesh", load_required_asset(mesh_path))
|
||||
mesh_component.set_editor_property("relative_scale3d", config.get("scale", unreal.Vector(1.0, 1.0, 1.0)))
|
||||
|
||||
unreal.BlueprintEditorLibrary.compile_blueprint(blueprint)
|
||||
unreal.EditorAssetLibrary.save_loaded_asset(blueprint)
|
||||
|
||||
|
||||
def main():
|
||||
for folder in (RESOURCE_FOLDER, STRUCTURE_FOLDER, WILDLIFE_FOLDER):
|
||||
unreal.EditorAssetLibrary.make_directory(folder)
|
||||
|
||||
for config in BLUEPRINTS:
|
||||
blueprint = create_or_load_blueprint(config["asset"], config["folder"], config["parent"])
|
||||
apply_defaults(blueprint, config)
|
||||
unreal.log(f"Configured Blueprint: {config['folder']}/{config['asset']}")
|
||||
|
||||
unreal.log("Agrarian playable Blueprint setup complete.")
|
||||
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user