diff --git a/docs/superpowers/plans/2026-07-27-unity-humanoid-animation-import.md b/docs/superpowers/plans/2026-07-27-unity-humanoid-animation-import.md new file mode 100644 index 00000000..a58e9203 --- /dev/null +++ b/docs/superpowers/plans/2026-07-27-unity-humanoid-animation-import.md @@ -0,0 +1,131 @@ +# Unity Humanoid Animation Import Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a Unity editor import hook that applies the shared Cityboy humanoid avatar and root transform clip settings to Actor animation FBX imports. + +**Architecture:** Create a small pure-policy helper plus an `AssetPostprocessor` wrapper in the existing editor assembly. EditMode tests exercise the helper so behavior can be verified without importing binary FBX assets. + +**Tech Stack:** Unity Editor C#, `UnityEditor.ModelImporter`, `UnityEditor.ModelImporterClipAnimation`, NUnit EditMode tests. + +## Global Constraints + +- Scope is `Assets/Game/Art/Actor/`. +- Exclude `Assets/Game/Art/Actor/cityboy/cityboy_sk.fbx`. +- Only mutate imports that have one or more animation clips. +- Use `Assets/Game/Art/Actor/cityboy/cityboy_sk.fbx` as the source avatar asset path. +- Do not touch existing FBX, prefab, or controller asset files. + +--- + +### Task 1: Import Policy Tests And Helper + +**Files:** +- Create: `Client/Assets/Script/Editor/HumanoidAnimationFbxImportSettings.cs` +- Create: `Client/Assets/Script/Tests/EditMode/HumanoidAnimationFbxImportSettingsTests.cs` +- Modify: `Client/Assets/Script/Tests/EditMode/XWorld.Link.EditModeTests.asmdef` + +**Interfaces:** +- Produces: `HumanoidAnimationFbxImportSettings.ShouldProcessAsset(string assetPath, bool hasAnimationClips) : bool` +- Produces: `HumanoidAnimationFbxImportSettings.ApplyClipSettings(ModelImporterClipAnimation clip) : ModelImporterClipAnimation` +- Produces: `HumanoidAnimationFbxImportSettings.CityboyAvatarPath : string` + +- [ ] **Step 1: Write failing EditMode tests** + +```csharp +using NUnit.Framework; +using UnityEditor; + +public sealed class HumanoidAnimationFbxImportSettingsTests +{ + [Test] + public void ShouldProcessActorAnimationFbx() + { + Assert.That( + HumanoidAnimationFbxImportSettings.ShouldProcessAsset( + "Assets/Game/Art/Actor/Controller/Class/Caster/Standing Walk Forward.fbx", + true), + Is.True); + } + + [Test] + public void ShouldNotProcessCityboySourceAvatar() + { + Assert.That( + HumanoidAnimationFbxImportSettings.ShouldProcessAsset( + HumanoidAnimationFbxImportSettings.CityboyAvatarPath, + true), + Is.False); + } + + [Test] + public void ShouldNotProcessActorFbxWithoutAnimationClips() + { + Assert.That( + HumanoidAnimationFbxImportSettings.ShouldProcessAsset( + "Assets/Game/Art/Actor/captain/captain.fbx", + false), + Is.False); + } + + [Test] + public void ApplyClipSettingsUsesOriginalRotationAndBakesRotationAndY() + { + var clip = new ModelImporterClipAnimation + { + lockRootRotation = false, + keepOriginalOrientation = false, + lockRootHeightY = false + }; + + ModelImporterClipAnimation updated = HumanoidAnimationFbxImportSettings.ApplyClipSettings(clip); + + Assert.That(updated.lockRootRotation, Is.True); + Assert.That(updated.keepOriginalOrientation, Is.True); + Assert.That(updated.lockRootHeightY, Is.True); + } +} +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: Unity EditMode tests for `HumanoidAnimationFbxImportSettingsTests`. + +Expected: compile/test failure because `HumanoidAnimationFbxImportSettings` does not exist. + +- [ ] **Step 3: Implement minimal helper** + +Create `HumanoidAnimationFbxImportSettings` with the constants and pure helper methods used by the tests. + +- [ ] **Step 4: Run test to verify it passes** + +Run: Unity EditMode tests for `HumanoidAnimationFbxImportSettingsTests`. + +Expected: all tests in the fixture pass. + +### Task 2: AssetPostprocessor Integration + +**Files:** +- Modify: `Client/Assets/Script/Editor/HumanoidAnimationFbxImportSettings.cs` +- Test: `Client/Assets/Script/Tests/EditMode/HumanoidAnimationFbxImportSettingsTests.cs` + +**Interfaces:** +- Consumes: `HumanoidAnimationFbxImportSettings.ShouldProcessAsset(string assetPath, bool hasAnimationClips) : bool` +- Consumes: `HumanoidAnimationFbxImportSettings.ApplyClipSettings(ModelImporterClipAnimation clip) : ModelImporterClipAnimation` +- Produces: `HumanoidAnimationFbxPostprocessor : AssetPostprocessor` + +- [ ] **Step 1: Add AssetPostprocessor implementation** + +Use `OnPreprocessModel` to get the `ModelImporter`, check scope and clip count, load the Cityboy avatar, set humanoid/copy-from-other settings, and update `clipAnimations`. + +- [ ] **Step 2: Run editor compilation/tests** + +Run Unity EditMode tests. + +Expected: editor code compiles and the helper tests still pass. + +- [ ] **Step 3: Inspect git diff** + +Run: `git diff -- Client/Assets/Script/Editor/HumanoidAnimationFbxImportSettings.cs Client/Assets/Script/Tests/EditMode/HumanoidAnimationFbxImportSettingsTests.cs Client/Assets/Script/Tests/EditMode/XWorld.Link.EditModeTests.asmdef` + +Expected: only the new importer helper/postprocessor and test assembly reference changes are present. diff --git a/docs/superpowers/specs/2026-07-27-unity-humanoid-animation-import-design.md b/docs/superpowers/specs/2026-07-27-unity-humanoid-animation-import-design.md new file mode 100644 index 00000000..66b67150 --- /dev/null +++ b/docs/superpowers/specs/2026-07-27-unity-humanoid-animation-import-design.md @@ -0,0 +1,32 @@ +# Unity Humanoid Animation Import Design + +## Goal + +Automatically apply the project's shared humanoid animation import settings when FBX animation assets are imported under `Assets/Game/Art/Actor/`. + +## Scope + +- Applies to `.fbx` assets inside `Assets/Game/Art/Actor/`. +- Excludes `Assets/Game/Art/Actor/cityboy/cityboy_sk.fbx`, because it provides the source avatar. +- Applies only when the FBX import has animation clips. +- Does not modify existing FBX, prefab, or controller assets directly. + +## Import Behavior + +When an in-scope FBX with animation clips is imported: + +- Set Rig `Animation Type` to `Humanoid`. +- Set Avatar to `Copy From Other`. +- Use `Cityboy_sk Avatar` from `Assets/Game/Art/Actor/cityboy/cityboy_sk.fbx`. +- For every imported animation clip: + - Enable Root Transform Rotation `Bake Into Pose`. + - Set Root Transform Rotation `Based Upon` to `Original`. + - Enable Root Transform Position (Y) `Bake Into Pose`. + +## Error Handling + +If the Cityboy avatar cannot be loaded, the importer logs a warning and leaves the asset unchanged. This avoids blocking Unity's asset import pipeline. + +## Testing + +Editor tests cover the path filter, avatar exclusion, and clip-setting mutation logic without importing real FBX files.