Add MVP character proxy selection
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import unreal
|
||||
|
||||
|
||||
MATERIAL_FOLDER = "/Game/Agrarian/Characters/Materials"
|
||||
CHARACTER_PROXY_MATERIALS = {
|
||||
"M_AGR_CharacterProxy_Workwear_Male": {
|
||||
"color": unreal.LinearColor(0.23, 0.20, 0.15, 1.0),
|
||||
"roughness": 0.88,
|
||||
},
|
||||
"M_AGR_CharacterProxy_Workwear_Female": {
|
||||
"color": unreal.LinearColor(0.20, 0.24, 0.18, 1.0),
|
||||
"roughness": 0.88,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def ensure_character_proxy_materials():
|
||||
unreal.EditorAssetLibrary.make_directory(MATERIAL_FOLDER)
|
||||
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
|
||||
created = []
|
||||
|
||||
for asset_name, spec in CHARACTER_PROXY_MATERIALS.items():
|
||||
asset_path = f"{MATERIAL_FOLDER}/{asset_name}"
|
||||
material = unreal.EditorAssetLibrary.load_asset(asset_path)
|
||||
if not material:
|
||||
material = asset_tools.create_asset(asset_name, MATERIAL_FOLDER, unreal.Material, unreal.MaterialFactoryNew())
|
||||
if not material:
|
||||
raise RuntimeError(f"Could not create character proxy material: {asset_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)
|
||||
created.append(asset_path)
|
||||
|
||||
unreal.EditorAssetLibrary.save_loaded_asset(material)
|
||||
|
||||
return created
|
||||
|
||||
|
||||
def main():
|
||||
created = ensure_character_proxy_materials()
|
||||
if created:
|
||||
for asset_path in created:
|
||||
unreal.log(f"Created MVP character proxy material: {asset_path}")
|
||||
else:
|
||||
unreal.log("MVP character proxy materials already exist.")
|
||||
|
||||
|
||||
main()
|
||||
@@ -27,15 +27,17 @@ EXPECTED = {
|
||||
"Selected",
|
||||
"Click a card or use Left/Right",
|
||||
"GetSelectedCharacterLabel",
|
||||
"NativeOnMouseButtonDown",
|
||||
"IsPointInside(LocalMousePosition, MaleCardPosition, CardSize)",
|
||||
"IsPointInside(LocalMousePosition, FemaleCardPosition, CardSize)",
|
||||
"HandleMaleCharacterClicked",
|
||||
"HandleFemaleCharacterClicked",
|
||||
"AgrarianSelectCharacter male",
|
||||
"AgrarianSelectCharacter female",
|
||||
],
|
||||
"AgrarianGamePlayerController.h": [
|
||||
"AgrarianSelectCharacter",
|
||||
],
|
||||
"AgrarianGamePlayerController.cpp": [
|
||||
"AgrarianSelectCharacter",
|
||||
"ApplyMvpCharacterProxyToPawn",
|
||||
"SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale)",
|
||||
"SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale)",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify first MVP male/female playable character proxy setup."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CONTROLLER_H = ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.h"
|
||||
CONTROLLER_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.cpp"
|
||||
FRONTEND_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianMvpFrontendWidget.cpp"
|
||||
CONFIG = ROOT / "Config" / "DefaultGame.ini"
|
||||
DOC = ROOT / "Docs" / "Characters" / "MvpCharacterProxies.md"
|
||||
SETUP = ROOT / "Scripts" / "setup_mvp_character_proxies.py"
|
||||
ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md"
|
||||
MALE_MATERIAL = ROOT / "Content" / "Agrarian" / "Characters" / "Materials" / "M_AGR_CharacterProxy_Workwear_Male.uasset"
|
||||
FEMALE_MATERIAL = ROOT / "Content" / "Agrarian" / "Characters" / "Materials" / "M_AGR_CharacterProxy_Workwear_Female.uasset"
|
||||
|
||||
|
||||
def require(condition: bool, message: str) -> None:
|
||||
if not condition:
|
||||
raise SystemExit(f"FAILED: {message}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
controller_h = CONTROLLER_H.read_text(encoding="utf-8")
|
||||
controller = CONTROLLER_CPP.read_text(encoding="utf-8")
|
||||
frontend = FRONTEND_CPP.read_text(encoding="utf-8")
|
||||
config = CONFIG.read_text(encoding="utf-8")
|
||||
doc = DOC.read_text(encoding="utf-8")
|
||||
setup = SETUP.read_text(encoding="utf-8")
|
||||
roadmap = ROADMAP.read_text(encoding="utf-8")
|
||||
|
||||
for token in (
|
||||
"ApplyMvpCharacterProxyToPawn",
|
||||
"SelectedMvpCharacterProxyId",
|
||||
):
|
||||
require(token in controller_h, f"controller header missing {token}")
|
||||
|
||||
for token in (
|
||||
"SKM_Manny_Simple",
|
||||
"SKM_Quinn_Simple",
|
||||
"M_AGR_CharacterProxy_Workwear_Male",
|
||||
"M_AGR_CharacterProxy_Workwear_Female",
|
||||
"SetSkeletalMesh",
|
||||
"SetMaterial",
|
||||
"SelectedMvpCharacterProxyId = TEXT(\"male\")",
|
||||
"SelectedMvpCharacterProxyId = TEXT(\"female\")",
|
||||
"ApplyMvpCharacterProxyToPawn();",
|
||||
):
|
||||
require(token in controller, f"controller implementation missing {token}")
|
||||
|
||||
for token in (
|
||||
"AgrarianSelectCharacter female",
|
||||
"AgrarianSelectCharacter male",
|
||||
"practical workwear proxy",
|
||||
):
|
||||
require(token in frontend, f"frontend character proxy flow missing {token}")
|
||||
|
||||
for token in (
|
||||
"M_AGR_CharacterProxy_Workwear_Male",
|
||||
"M_AGR_CharacterProxy_Workwear_Female",
|
||||
"MaterialFactoryNew",
|
||||
"MP_BASE_COLOR",
|
||||
"MP_ROUGHNESS",
|
||||
):
|
||||
require(token in setup, f"setup script missing {token}")
|
||||
|
||||
require(
|
||||
'+DirectoriesToAlwaysCook=(Path="/Game/Agrarian/Characters")' in config,
|
||||
"character proxy folder is not always cooked",
|
||||
)
|
||||
|
||||
for token in (
|
||||
"SKM_Manny_Simple",
|
||||
"SKM_Quinn_Simple",
|
||||
"not final production humans",
|
||||
"Final character work should replace these proxies",
|
||||
):
|
||||
require(token in doc, f"character proxy doc missing {token}")
|
||||
|
||||
require(
|
||||
"- [x] Add first realistic playable character proxies for the selected young adult male and female archetypes" in roadmap,
|
||||
"0.1.O character proxy roadmap item is not checked off",
|
||||
)
|
||||
require(MALE_MATERIAL.exists(), "male character proxy material asset is missing")
|
||||
require(FEMALE_MATERIAL.exists(), "female character proxy material asset is missing")
|
||||
|
||||
print("OK: MVP male/female playable character proxy flow is wired and documented.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user