From 744b3c35e20a53727c58a549e57073ff0ae4042c Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 14 May 2026 00:08:45 +0000 Subject: [PATCH] Add interact input assets --- AGRARIAN_DEVELOPMENT_ROADMAP.md | 13 ++- Content/Input/Actions/IA_Interact.uasset | 3 + Content/Input/IMC_Default.uasset | 4 +- .../Blueprints/BP_ThirdPersonCharacter.uasset | 4 +- Scripts/RunUnrealPython-Windows.bat | 36 ++++++++ Scripts/setup_interact_input.py | 86 +++++++++++++++++++ Scripts/verify_interact_input.py | 44 ++++++++++ 7 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 Content/Input/Actions/IA_Interact.uasset create mode 100644 Scripts/RunUnrealPython-Windows.bat create mode 100644 Scripts/setup_interact_input.py create mode 100644 Scripts/verify_interact_input.py diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index b13506a..e9a99ec 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -125,15 +125,20 @@ Completed in version .01: - [x] Added replicated wildlife base actor. - [x] Built `AgrarianGameEditor Win64 Development` successfully on Windows-Builder. - [x] Added a Codex headless Windows build lane through `/home/nathan/bin/agrarian-build-editor`. +- [x] Added a project-local Unreal Python execution wrapper for headless editor asset updates. - [x] Installed VS 2022 Build Tools MSVC `14.44.35207` for Unreal 5.7 compatibility. - [x] Fixed `AAgrarianDebugHUD` compile issue caused by `const` HUD helper methods calling non-const `AHUD::DrawText`. +- [x] Confirmed the project loads through Unreal Editor command mode and the default test map passes map check. +- [x] Created `IA_Interact` input action. +- [x] Bound `IA_Interact` to `E` and `Gamepad_FaceButton_Left`. +- [x] Assigned `IA_Interact` to the character Blueprint's `InteractAction`. Open version .01 tasks: -- [ ] Confirm the project opens cleanly in Unreal Editor after the latest wildlife commit. -- [ ] Create `IA_Interact` input action. -- [ ] Bind `IA_Interact` to `E` and a gamepad button. -- [ ] Assign `IA_Interact` to the character Blueprint's `InteractAction`. +- [x] Confirm the project opens cleanly in Unreal Editor after the latest wildlife commit. +- [x] Create `IA_Interact` input action. +- [x] Bind `IA_Interact` to `E` and a gamepad button. +- [x] Assign `IA_Interact` to the character Blueprint's `InteractAction`. - [ ] Create item definition assets for wood, stone, fiber, food, meat, hide, and primitive structure parts. - [ ] Create recipe data assets for campfire, primitive shelter, basic tool, and bandage. - [ ] Create Blueprint child actors for wood resource, campfire, primitive shelter, and first wildlife species. diff --git a/Content/Input/Actions/IA_Interact.uasset b/Content/Input/Actions/IA_Interact.uasset new file mode 100644 index 0000000..cf8fdfc --- /dev/null +++ b/Content/Input/Actions/IA_Interact.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89ddb8beb187ca01503ca6863009b66c881723f663c44ac696f5f377debd30ce +size 1170 diff --git a/Content/Input/IMC_Default.uasset b/Content/Input/IMC_Default.uasset index b63309a..a6df8b1 100644 --- a/Content/Input/IMC_Default.uasset +++ b/Content/Input/IMC_Default.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:133bda6567aaeea1aae05c03597345e4b1d9ef24d868a0275203b3203a7aae98 -size 7787 +oid sha256:17973918542e1a0695a8b9f00893e9d7d066a8dbcf64bd3b7d23e8609ad62bd4 +size 8651 diff --git a/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset b/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset index c299638..ebc0850 100644 --- a/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset +++ b/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45e6eca3e0e2af0b2fdb9780db8ebfc24f63eac6c5d8721e82814722c81e63ed -size 54802 +oid sha256:f394cbf6d50d13c0d24f2c8861b933ee06d37dc2eb2296946775869b0aebd788 +size 51358 diff --git a/Scripts/RunUnrealPython-Windows.bat b/Scripts/RunUnrealPython-Windows.bat new file mode 100644 index 0000000..fb3e67b --- /dev/null +++ b/Scripts/RunUnrealPython-Windows.bat @@ -0,0 +1,36 @@ +@echo off +setlocal + +set "PROJECT_DIR=%~dp0.." +set "PROJECT_FILE=%PROJECT_DIR%\AgrarianGame.uproject" +set "UE_ROOT=C:\Program Files\Epic Games\UE_5.7" +set "EDITOR_CMD=%UE_ROOT%\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" + +if "%~1"=="" ( + echo Usage: %~nx0 ScriptRelativeOrAbsolutePath + exit /b 2 +) + +set "PYTHON_SCRIPT=%~f1" +if not exist "%PYTHON_SCRIPT%" set "PYTHON_SCRIPT=%PROJECT_DIR%\%~1" + +if not exist "%EDITOR_CMD%" ( + echo UnrealEditor-Cmd.exe was not found at: + echo %EDITOR_CMD% + exit /b 1 +) + +if not exist "%PROJECT_FILE%" ( + echo Project file was not found at: + echo %PROJECT_FILE% + exit /b 1 +) + +if not exist "%PYTHON_SCRIPT%" ( + echo Python script was not found at: + echo %PYTHON_SCRIPT% + exit /b 1 +) + +call "%EDITOR_CMD%" "%PROJECT_FILE%" -ExecutePythonScript="%PYTHON_SCRIPT%" -unattended -nop4 -nosplash -NullRHI -stdout -FullStdOutLogOutput -log="%PROJECT_DIR%\Saved\Logs\CodexPython.log" +exit /b %ERRORLEVEL% diff --git a/Scripts/setup_interact_input.py b/Scripts/setup_interact_input.py new file mode 100644 index 0000000..de03bd2 --- /dev/null +++ b/Scripts/setup_interact_input.py @@ -0,0 +1,86 @@ +import unreal + + +def load(path): + asset = unreal.EditorAssetLibrary.load_asset(path) + if not asset: + raise RuntimeError(f"Could not load {path}") + return asset + + +def create_input_action(path): + existing = unreal.EditorAssetLibrary.load_asset(path) + if existing: + return existing + + template_path = "/Game/Input/Actions/IA_Jump" + template = unreal.EditorAssetLibrary.load_asset(template_path) + if not template: + raise RuntimeError(f"Could not load input action template {template_path}") + + action = unreal.EditorAssetLibrary.duplicate_asset(template_path, path) + if not action: + raise RuntimeError(f"Could not create {path}") + return action + + +def set_boolean_value_type(action): + # UE exposes this enum as BOOLEAN in Python for Enhanced Input actions. + action.set_editor_property("value_type", unreal.InputActionValueType.BOOLEAN) + try: + action.set_editor_property("triggers", []) + except Exception as exc: + unreal.log_warning(f"Could not clear IA_Interact triggers; keeping template defaults: {exc}") + unreal.EditorAssetLibrary.save_loaded_asset(action) + + +def mapping_exists(context, action, key_name): + mapping_data = context.get_editor_property("default_key_mappings") + mappings = list(mapping_data.get_editor_property("mappings")) + for mapping in mappings: + mapping_key = mapping.get_editor_property("key") + if ( + mapping.get_editor_property("action") == action + and str(mapping_key.get_editor_property("key_name")) == key_name + ): + return True + return False + + +def map_key(context, action, key_name): + if mapping_exists(context, action, key_name): + unreal.log(f"Mapping already exists: {action.get_name()} -> {key_name}") + return + + key = unreal.Key() + key.set_editor_property("key_name", key_name) + mapping_data = context.get_editor_property("default_key_mappings") + mappings = list(mapping_data.get_editor_property("mappings")) + new_mapping = unreal.EnhancedActionKeyMapping() + new_mapping.set_editor_property("action", action) + new_mapping.set_editor_property("key", key) + mappings.append(new_mapping) + mapping_data.set_editor_property("mappings", mappings) + context.set_editor_property("default_key_mappings", mapping_data) + + unreal.log(f"Added mapping: {action.get_name()} -> {key_name}") + + +def main(): + interact_action = create_input_action("/Game/Input/Actions/IA_Interact") + set_boolean_value_type(interact_action) + + context = load("/Game/Input/IMC_Default") + map_key(context, interact_action, "E") + map_key(context, interact_action, "Gamepad_FaceButton_Left") + unreal.EditorAssetLibrary.save_loaded_asset(context) + + character_bp = load("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter") + character_cdo = unreal.get_default_object(character_bp.generated_class()) + character_cdo.set_editor_property("InteractAction", interact_action) + unreal.EditorAssetLibrary.save_loaded_asset(character_bp) + + unreal.log("Agrarian interact input setup complete.") + + +main() diff --git a/Scripts/verify_interact_input.py b/Scripts/verify_interact_input.py new file mode 100644 index 0000000..f8bf3c4 --- /dev/null +++ b/Scripts/verify_interact_input.py @@ -0,0 +1,44 @@ +import unreal + + +def load(path): + asset = unreal.EditorAssetLibrary.load_asset(path) + if not asset: + raise RuntimeError(f"Could not load {path}") + return asset + + +def mapping_found(context, action, key_name): + mapping_data = context.get_editor_property("default_key_mappings") + for mapping in list(mapping_data.get_editor_property("mappings")): + mapping_key = mapping.get_editor_property("key") + if ( + mapping.get_editor_property("action") == action + and str(mapping_key.get_editor_property("key_name")) == key_name + ): + return True + return False + + +def main(): + action = load("/Game/Input/Actions/IA_Interact") + context = load("/Game/Input/IMC_Default") + character_bp = load("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter") + character_cdo = unreal.get_default_object(character_bp.generated_class()) + + missing = [] + for key_name in ["E", "Gamepad_FaceButton_Left"]: + if not mapping_found(context, action, key_name): + missing.append(f"missing mapping {key_name}") + + assigned_action = character_cdo.get_editor_property("InteractAction") + if assigned_action != action: + missing.append("BP_ThirdPersonCharacter InteractAction is not IA_Interact") + + if missing: + raise RuntimeError("Interact input verification failed: " + "; ".join(missing)) + + unreal.log("Agrarian interact input verification complete.") + + +main()