# 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.