Files
zeling_v2/Docs/ThirdPart/Animancer_Technical_Evaluation.md
2026-05-19 23:20:44 +08:00

1786 lines
61 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Animancer Pro v8.3.0 技术评估与使用手册
> **版本**: Animancer Pro 8.3.0 (2026-03-28)
> **Unity 要求**: 2022.3+
> **依赖**: `com.unity.modules.animation`
> **许可**: Unity Asset Store EULA
> **包路径**: `Packages/com.kybernetik.animancer/`
> **官方文档**: https://kybernetik.com.au/animancer/
> **API 文档**: https://kybernetik.com.au/animancer/api/Animancer/
> **命名空间**: `Animancer`、`Animancer.FSM`、`Animancer.TransitionLibraries`
---
## 目录
1. [概述与设计哲学](#1-概述与设计哲学)
2. [架构总览](#2-架构总览)
3. [核心组件](#3-核心组件)
4. [节点层级体系 (Nodes)](#4-节点层级体系-nodes)
5. [状态系统 (States)](#5-状态系统-states)
6. [Transition 系统](#6-transition-系统)
7. [事件系统 (Events)](#7-事件系统-events)
8. [Fade 与权重系统](#8-fade-与权重系统)
9. [Mixer 状态 (混合树等价)](#9-mixer-状态-混合树等价)
10. [动画层 (Layers)](#10-动画层-layers)
11. [Controller State (Mecanim 兼容)](#11-controller-state-mecanim-兼容)
12. [内置有限状态机 (FSM)](#12-内置有限状态机-fsm)
13. [参数系统 (Parameters)](#13-参数系统-parameters)
14. [高级特性](#14-高级特性)
15. [Editor 工具链](#15-editor-工具链)
16. [数据类型与工具](#16-数据类型与工具)
17. [Animancer vs Unity Mecanim 详细对比](#17-animancer-vs-unity-mecanim-详细对比)
18. [性能分析](#18-性能分析)
19. [与 BaseGames 架构集成方案](#19-与-basegames-架构集成方案)
20. [优缺点总结](#20-优缺点总结)
21. [总结与建议](#21-总结与建议)
---
## 1. 概述与设计哲学
### 1.1 什么是 Animancer
Animancer 是基于 Unity **Playables API** 的动画插件,核心理念:
> **用代码直接控制动画,不需要 Animator Controller 状态机。**
传统 Unity 动画工作流要求在 Animator Controller 中建立状态图(Mecanim),然后通过 `SetTrigger`/`SetBool` 间接驱动转换。Animancer 移除这个中间层,让开发者直接在 C# 代码中调用 `Play(clip)` 播放任何 `AnimationClip`
### 1.2 核心设计原则
| 原则 | 说明 |
|------|------|
| **简洁性** | 一行代码即可播放动画,无需预配置状态图 |
| **透明性** | 所有内部状态均可访问和调试,附带完整源码 |
| **适应性** | 不强制单一组织方式,脚本自由决定动画逻辑 |
| **安全性** | 直接引用 AnimationClip 对象,无魔法字符串 |
| **清晰性** | 字段声明即需求列表 |
| **可靠性** | 始终执行最后一个 `Play()` 调用,不会吞掉命令 |
### 1.3 底层实现
Animancer 仍然使用 Unity 底层基础设施:
- `Animator` 组件(必须存在于 GameObject 上)
- `PlayableGraph` 和各种 `Playable` 节点
- `AnimationClip` 资源
**不需要** 的是:
- `RuntimeAnimatorController` 资产
- Animator 窗口中的状态机图形编辑器
- Animator Parameters、Transitions、Blend Trees 的图形化配置
---
## 2. 架构总览
### 2.1 Playable Graph 层级
```
PlayableGraph (Unity 底层)
└── AnimancerLayerMixerList (根 Playable — AnimationLayerMixerPlayable)
├── AnimancerLayer[0] (AnimationMixerPlayable)
│ ├── ClipState (AnimationClipPlayable) ── AnimationClip
│ ├── ClipState (AnimationClipPlayable) ── AnimationClip
│ ├── MixerState (AnimationMixerPlayable)
│ │ ├── ClipState ── walk
│ │ └── ClipState ── run
│ └── ControllerState (AnimatorControllerPlayable)
├── AnimancerLayer[1] (AnimationMixerPlayable)
│ └── ClipState ── 上半身覆盖
└── ...更多层 (默认最多 4 层,可扩展)
```
### 2.2 核心类关系
```
AnimancerComponent (MonoBehaviour — 主入口)
├── Animator (Unity 组件引用)
└── AnimancerGraph (核心管理器)
├── PlayableGraph (Unity Playable 图)
├── AnimancerLayerMixerList → AnimancerLayer[]
├── AnimancerStateDictionary (Object → AnimancerState 映射)
├── ParameterDictionary (命名参数池)
├── NamedEventDictionary (命名事件回调)
├── PreUpdatables / PostUpdatables (自定义更新队列)
└── DefaultFadeDuration = 0.25f (静态默认淡入时长)
AnimancerNodeBase (抽象基类)
├── AnimancerGraph (根节点)
└── AnimancerNode (抽象可播放节点)
├── AnimancerLayer (层)
└── AnimancerState (抽象状态基类)
├── ClipState — 单个 AnimationClip
├── ControllerState — RuntimeAnimatorController
├── PlayableAssetState — Timeline PlayableAsset
├── AnimationJobState<T> — 自定义 Animation Job
├── SequenceState — 序列播放
└── ParentState (抽象容器)
├── ManualMixerState — 手动权重混合
└── MixerState<T> — 参数化混合
├── LinearMixerState — 1D 线性混合
└── Vector2MixerState (抽象)
├── CartesianMixerState — 笛卡尔 2D
└── DirectionalMixerState — 极坐标 2D
```
### 2.3 数据流
```
用户代码
→ animancer.Play(ClipTransition)
→ AnimancerGraph.Play()
→ AnimancerStateDictionary.GetOrCreate(transition)
→ transition.CreateState() / transition.Apply(state)
→ AnimancerLayer.Play(state, fadeDuration, fadeMode)
→ FadeGroup 管理权重淡入淡出
→ PlayableGraph 评估 (每帧)
→ Animator 应用骨骼变换
```
### 2.4 完整目录结构 (171 个源文件)
```
Packages/com.kybernetik.animancer/
├── Runtime/ # 171 个源文件
│ ├── AnimancerComponent.cs # 主入口 MonoBehaviour
│ ├── HybridAnimancerComponent.cs # Animator Controller + Animancer 混合
│ ├── NamedAnimancerComponent.cs # 命名动画组件
│ ├── SoloAnimation.cs # 单动画精简组件
│ ├── Core/
│ │ ├── AnimancerGraph.cs # 核心 Playable 图管理器
│ │ ├── AnimancerLayerList.cs # 层列表抽象
│ │ ├── AnimancerLayerMixerList.cs # 层混合器
│ │ ├── AnimancerStateDictionary.cs # 状态注册表
│ │ ├── AnimancerUtilities.cs # 扩展方法
│ │ ├── UpdatableListPlayable.cs # 自定义 Playable
│ │ ├── Events/ (9 文件) # 事件系统
│ │ │ ├── AnimancerEvent.cs
│ │ │ ├── AnimancerEvent.Sequence.cs
│ │ │ ├── AnimancerEvent.Dispatcher.cs
│ │ │ ├── AnimancerEvent.Invoker*.cs (3 种)
│ │ │ ├── AnimancerEvent.Invocation.cs
│ │ │ ├── AnimancerState.Events.cs
│ │ │ ├── NamedEventDictionary.cs
│ │ │ └── Invokables/ (Parameter<T>, UnityEvent 等)
│ │ ├── Fades/ (2 文件)
│ │ │ ├── FadeGroup.cs # 权重淡入淡出管理
│ │ │ └── NodeWeight.cs # 节点权重
│ │ ├── Nodes/ (10 文件) # 状态层级
│ │ │ ├── AnimancerNodeBase.cs
│ │ │ ├── AnimancerNode.cs
│ │ │ ├── AnimancerState.cs + ExpectFade.cs
│ │ │ ├── AnimancerLayer.cs
│ │ │ ├── ClipState.cs
│ │ │ ├── ParentState.cs
│ │ │ ├── PlayableAssetState.cs
│ │ │ ├── SequenceState.cs
│ │ │ └── AnimationJobState.cs
│ │ └── Weighted Mask Layers/ (4 文件)
│ │ ├── WeightedMaskLayers.cs
│ │ ├── WeightedMaskLayersDefinition.cs
│ │ ├── WeightedMaskLayerList.cs
│ │ └── WeightedMaskMixerJob.cs
│ ├── Controller States/ (2 文件)
│ │ ├── ControllerState.cs
│ │ └── ControllerState.ParameterBinding.cs
│ ├── Mixer States/ (7 文件)
│ │ ├── ManualMixerState.cs
│ │ ├── MixerStateT.cs
│ │ ├── LinearMixerState.cs
│ │ ├── Vector2MixerState.cs
│ │ ├── CartesianMixerState.cs
│ │ ├── DirectionalMixerState.cs
│ │ └── NodeParameter.cs
│ ├── Data Types/ (15 文件)
│ │ ├── FadeMode.cs
│ │ ├── StringReference.cs / StringAsset.cs
│ │ ├── Updatable.cs / FastEnumerator.cs / IndexedList.cs
│ │ ├── Parameters/ (6 文件)
│ │ │ ├── ParameterDictionary.cs
│ │ │ ├── Parameter.cs
│ │ │ ├── SmoothedFloatParameter.cs
│ │ │ └── SmoothedVector2Parameter.cs
│ │ └── Object Pooling/ (6 文件)
│ │ ├── ObjectPool<T>.cs
│ │ ├── ListPool / DictionaryPool / SetPool / CollectionPool
│ │ └── StringBuilderPool
│ ├── Interfaces/ (16 文件)
│ │ IAnimancerComponent, ITransition, IState, IMotion,
│ │ IUpdatable, IHasKey, IHasEvents, IHasDescription,
│ │ ICloneable<T>, ICopyable<T>, IConvertable<T>,
│ │ ICharacterRoot, IPolymorphic, IWrapper, IInitializable, IInvokable
│ └── Utilities/
│ ├── Transitions/ (25 文件)
│ │ ├── Transition.cs (基类)
│ │ ├── TransitionAsset.cs / TransitionAssetBase.cs / TransitionAssetT.cs
│ │ ├── TransitionAssetReference.cs
│ │ ├── Transition Types/
│ │ │ ├── ClipTransition.cs
│ │ │ ├── ClipTransitionSequence.cs
│ │ │ ├── ControllerTransition.cs
│ │ │ ├── PlayableAssetTransition.cs
│ │ │ ├── ManualMixerTransition.cs
│ │ │ ├── LinearMixerTransition.cs
│ │ │ ├── MixerTransition2D.cs
│ │ │ └── TransitionSequence.cs
│ │ └── Transition Libraries/ (6 文件)
│ │ ├── TransitionLibrary.cs
│ │ ├── TransitionLibraryAsset.cs
│ │ ├── TransitionLibraryDefinition.cs
│ │ ├── TransitionModifierDefinition.cs
│ │ └── NamedIndex.cs
│ ├── FSM/ (12 文件)
│ │ ├── IState.cs
│ │ ├── StateMachine1.cs + WithDefault + InputBuffer + StateSelector
│ │ ├── StateMachine2.cs + WithDefault + InputBuffer
│ │ ├── StateBehaviour.cs
│ │ ├── DelegateState.cs
│ │ ├── StateChange.cs / KeyChange.cs
│ │ └── StateMachineUtilities.cs
│ ├── Animation Jobs/ (5 文件)
│ │ AnimancerJob, AnimatedBool/Int/Float, AnimatedProperty
│ ├── Custom Fade/ (4 文件)
│ │ Easing.cs, DontAllowFade.cs, FadeGroupExtensions.cs,
│ │ MixerChildFade.cs
│ ├── Directional Animations/ (10 文件)
│ │ DirectionalAnimations3D, DirectionalAnimationSet2/4/8,
│ │ DirectionalClipTransition, Directions
│ ├── Redirect Root Motion/ (4 文件)
│ │ RedirectRootMotion (base), →Transform, →Rigidbody,
│ │ →CharacterController
│ └── TimeSynchronizer.cs, SpriteRendererTextureSwap.cs,
│ ExitEvent.cs, PlayableOutputRefresher.cs,
│ ExposedPropertyTable.cs
├── Editor/ # 编辑器工具
│ ├── Animancer Tools/ (窗口工具集)
│ ├── Transition Libraries/ (可视化编辑)
│ ├── Transition Previews/ (动画预览)
│ ├── Previews/
│ ├── GUI/ (Inspector 自定义绘制)
│ ├── Caching/ (编辑器缓存)
│ └── Serialization/
├── Samples~/ (示例场景)
│ ├── 01 Basics/
│ ├── 02 Fine Control/
│ ├── 03 Mixers/
│ ├── 04 Layers/
│ ├── 05 Events/
│ ├── 06 State Machines/
│ ├── 07 Sprites/
│ ├── 08 Animator Controllers/
│ ├── 09 Inverse Kinematics/
│ ├── 10 Animation Jobs/
│ └── Code/ (共用代码)
└── Art/ (示例美术资源)
```
---
## 3. 核心组件
### 3.1 AnimancerComponent
**主入口组件**,挂载在拥有 `Animator` 的 GameObject 上。
```csharp
[AddComponentMenu("Animancer/Animancer Component")]
[DefaultExecutionOrder(-5000)]
public class AnimancerComponent : MonoBehaviour,
IAnimancerComponent, IEnumerator, IAnimationClipSource, IAnimationClipCollection
{
// ─── 核心引用 ───
[SerializeField] private Animator _Animator;
public AnimancerGraph Graph { get; } // 惰性初始化
// ─── 播放接口 ───
AnimancerState Play(AnimationClip clip);
AnimancerState Play(AnimationClip clip, float fadeDuration);
AnimancerState Play(ITransition transition);
AnimancerState Play(ITransition transition, float fadeDuration, FadeMode fadeMode);
// ─── 便捷访问 ───
AnimancerLayerList Layers { get; } // 动画层列表
AnimancerStateDictionary States { get; } // 状态注册表
ParameterDictionary Parameters { get; } // 参数字典
NamedEventDictionary Events { get; } // 命名事件字典
TransitionLibraryAsset Transitions { get; } // 转换库 (Pro)
// ─── 生命周期 ───
AnimatorUpdateMode UpdateMode { get; set; }
DisableAction ActionOnDisable { get; set; } // 禁用时行为
bool IsGraphPlaying { get; set; }
// ─── 实用方法 ───
void Stop();
void Destroy();
}
```
**DisableAction 枚举**:
| 值 | 行为 |
|----|------|
| `Stop` | 停止并重置,保留当前值 |
| `Pause` | 暂停以便后续恢复 |
| `Continue` | 非激活时继续播放 |
| `Reset` | 停止并重新绑定 Animator |
| `Destroy` | 完全销毁 PlayableGraph |
**关键设计点**
- 自动在 `OnEnable` 初始化 `AnimancerGraph`
-`OnDisable` 根据 `ActionOnDisable` 处理图
- 不需要 `RuntimeAnimatorController`
- `Play()` 返回 `AnimancerState`,允许链式操作
- 支持 `yield` 等待所有动画完成
### 3.2 HybridAnimancerComponent (Pro)
允许**同时**使用 Animator Controller 和 Animancer。主 Controller 作为 Layer 0 的默认状态,可以在其上叠加 Animancer 播放的单独 Clips。
用途:**渐进式迁移** — 保留现有 Animator Controller逐步将状态迁移到纯代码驱动。
### 3.3 NamedAnimancerComponent
通过字符串名称注册和查找动画:
```csharp
public class NamedAnimancerComponent : AnimancerComponent
{
[SerializeField] private StringAsset[] _Names; // v8.3 新增:可选自定义名称
[SerializeField] private AnimationClip[] _Animations;
// Awake 中将所有 clip 注册到字典,可通过名称查找
// 若 _Names[i] 非空,则以 StringAsset 作为键;否则回退到 clip.name
}
```
### 3.4 SoloAnimation
最简化组件 — 只播放一个动画,替代 Animator + Controller 的最小配置:
```csharp
public class SoloAnimation : MonoBehaviour
{
[SerializeField] private Animator _Animator;
[SerializeField] private AnimationClip _Clip;
[SerializeField] private float _Speed = 1;
}
```
---
## 4. 节点层级体系 (Nodes)
### 4.1 AnimancerNodeBase (抽象根基类)
所有 Playable 节点的基础。
| 属性 | 类型 | 说明 |
|------|------|------|
| `Graph` | `AnimancerGraph` | 父图 |
| `Parent` | `AnimancerNodeBase` | 父节点 |
| `Layer` | `AnimancerLayer` | 所属层 |
| `ChildCount` | `int` | 子节点数量 |
| `Playable` | `Playable` | Unity Playable 包装 |
| `BaseWeight` | `float` | 权重贡献 (01) |
| `Speed` | `float` | 播放速度 |
| `EffectiveSpeed` | `float` | 含父节点乘积的最终速度 |
| `KeepChildrenConnected` | `bool` | 性能优化标志 |
| `ApplyAnimatorIK` | `bool` | Humanoid IK 支持 |
| `ApplyFootIK` | `bool` | 脚部 IK 支持 |
### 4.2 AnimancerNode (抽象可播放节点)
在 NodeBase 基础上增加:
| 属性/方法 | 说明 |
|-----------|------|
| `Index` | 在父节点端口索引 |
| `FadeGroup` | 淡入淡出管理器 |
| `CreatePlayable(out Playable)` | 抽象方法,创建底层 Playable |
| `DestroyPlayable()` | 销毁 Playable |
| `RecreatePlayable()` | 重建 Playable |
| `CopyFrom(AnimancerNode, CloneContext)` | 深拷贝 |
| `ConnectChildUnsafe(int, AnimancerNode)` | 快速连接 |
| `DisconnectChildSafe(int)` | 安全断开 |
| `IEnumerator` 支持 | 可 `yield` 等待 |
---
## 5. 状态系统 (States)
### 5.1 AnimancerState (抽象基类)
所有可播放动画单元的基类,核心 API
```csharp
public abstract class AnimancerState : AnimancerNode
{
// ─── 身份 ───
object Key { get; set; } // 注册表中的键
AnimancerLayer Layer { get; } // 所属层
AnimationClip Clip { get; } // 动画片段 (ClipState)
Object MainObject { get; } // 主资产引用
GameObject GameObject { get; } // 目标 GameObject
// ─── 时间控制 ───
float Time { get; set; } // 当前时间(秒)
double TimeD { get; set; } // 双精度时间
float NormalizedTime { get; set; } // 归一化时间 [0,1]
double RawTime { get; set; } // 原始时间
float RemainingDuration { get; } // 剩余时长
float Length { get; } // 动画总长度
bool IsLooping { get; } // 是否循环
// ─── 播放控制 ───
float Speed { get; set; } // 播放速度
float Weight { get; set; } // 混合权重 [0,1]
bool IsPlaying { get; set; } // 是否正在播放
bool IsActive { get; } // 权重 > 0
// ─── 事件 ───
AnimancerEvent.Sequence Events { get; } // 事件序列
AnimancerEvent.Sequence SharedEvents { get; set; }
// ─── Root Motion ───
Vector3 AverageVelocity { get; }
// ─── 方法 ───
void Play() / void Stop() / void Pause();
void Fade(float targetWeight, float? fadeDuration);
void Destroy();
void SetParent(AnimancerNode parent);
// ─── 关键 Pro 特性 ───
float ExpectFade { get; set; } // 预期淡入时长
int LayerIndex { get; } // 层索引
}
```
### 5.2 ClipState
最常用的状态类型 — 播放单个 AnimationClip
```csharp
public sealed class ClipState : AnimancerState
{
public AnimationClip Clip { get; }
// 内部创建 AnimationClipPlayable
// 支持所有 Rig 类型Humanoid, Generic, Sprite
}
```
### 5.3 PlayableAssetState (Pro)
包装 `PlayableAsset` (Timeline) 作为 Animancer 图中的一个节点,可与其他状态混合:
```csharp
animancer.Play(myTimelineTransition);
// Timeline 作为普通 AnimancerState 参与权重混合
```
### 5.4 SequenceState (Pro)
按顺序播放一系列子状态,支持子状态间淡入时间:
```csharp
public class SequenceState : ParentState, IUpdatable
{
void Set(params ITransition[] transitions);
float Length { get; } // 所有子动画总长度
}
```
### 5.5 AnimationJobState<T> (Pro)
运行自定义 `IAnimationJob`,实现程序化动画:
```csharp
public interface IAnimancerStateJob : IDisposable
{
float Length { get; }
bool IsLooping { get; }
void ProcessRootMotion(AnimationStream stream, double time);
void ProcessAnimation(AnimationStream stream, double time);
}
public class AnimationJobState<T> : AnimancerState, IUpdatable
where T : struct, IAnimancerStateJob
{
public T Job { get; set; }
}
```
### 5.6 AnimancerStateDictionary
状态注册表,映射键到状态:
```csharp
public class AnimancerStateDictionary
{
ClipState Create(AnimationClip clip);
ClipState Create(object key, AnimationClip clip);
AnimancerState GetOrCreate(ITransition transition);
AnimancerState Get(object key);
bool TryGet(object key, out AnimancerState state);
AnimancerState Current { get; } // Layer 0 当前状态
void Register(AnimancerState state);
void Unregister(AnimancerState state);
// ─── v8.3 新增 ───
bool TryGetAlias(object key, out AnimancerState state); // 优先通过 TransitionLibrary 别名查找
bool TryGetAlias(IHasKey hasKey, out AnimancerState state);
}
```
**TryGetAlias** (v8.3):先查 `TransitionLibrary` 是否将 `key` 映射为别名,再用最终键查找状态。`AnimancerGraph.IsPlaying` 内部已改用此方法,使得通过 Library 别名也能正确判断播放状态。
**Key 可以是**: AnimationClip、clip.name(字符串)、int、enum、自定义对象、IHasKey 实现。
---
## 6. Transition 系统
Transition 是 Animancer 的**核心数据架构层**,将动画播放参数封装为可序列化配置对象。
### 6.1 ITransition 接口
```csharp
public interface ITransition : IHasKey
{
float FadeDuration { get; set; }
FadeMode FadeMode { get; }
AnimancerState CreateState();
void Apply(AnimancerState state);
bool IsValid { get; }
bool IsLooping { get; }
float NormalizedStartTime { get; set; } // NaN = 不设置
float MaximumLength { get; }
float Speed { get; set; }
object Key { get; }
AnimancerEvent.Sequence Events { get; }
}
```
### 6.2 Transition 四级体系
| 级别 | 类型 | 序列化方式 | 适用场景 |
|------|------|-----------|---------|
| **Level 0** | `AnimationClip` | 直接引用 | 最简单,无参数配置 |
| **Level 1** | `ClipTransition` | `[SerializeField]` 字段 | 按实例配置,含 FadeDuration/Speed/Events |
| **Level 2** | `TransitionAsset` (SO) | ScriptableObject 资产 | 跨脚本/跨角色共享 |
| **Level 3** | `TransitionLibrary` (SO) | ScriptableObject 资产 | 集中管理 + 转换修正器 |
### 6.3 ClipTransition
最常用的 Transition 类型:
```csharp
[Serializable]
public class ClipTransition : Transition<ClipState>, IMotion, IAnimationClipCollection
{
[SerializeField] private AnimationClip _Clip;
[SerializeField] private float _NormalizedStartTime;
// 继承自 Transition<T>:
// float FadeDuration, float Speed, AnimancerEvent.Sequence Events
public override ClipState CreateState() => new ClipState(_Clip);
public float Length { get; }
public Vector3 AverageVelocity { get; } // Root Motion
public float AverageAngularSpeed { get; }
}
```
### 6.4 TransitionAsset (ScriptableObject)
```csharp
[CreateAssetMenu(menuName = "Animancer/Transition Asset")]
public class TransitionAsset : TransitionAsset<ITransition>
{
// 可在 Project 窗口右键创建
// 多角色共享同一配置
// 注意Events 不应存储在共享 Asset 上
// 正确做法state.Events(this).OnEnd ??= callback
}
```
### 6.5 TransitionLibraryAsset (Pro)
```csharp
[CreateAssetMenu(menuName = "Animancer/Transition Library")]
public class TransitionLibraryAsset : ScriptableObject
{
// 集中管理角色的所有 Transition
// 支持 ModifierA → B 时使用特殊淡入参数
// 类似 Animator Controller 的转换表
}
```
用途:当同一个"攻击"动画从"idle"进入和从"run"进入需要不同淡入时长时。
内部组件:
- `TransitionLibrary` — 运行时查找
- `TransitionLibraryDefinition` — 编辑器定义
- `TransitionModifierDefinition` — 转换修正器
- `NamedIndex` — 按名称索引
**v8.3 新增功能**
| 特性 | 说明 |
|------|------|
| **分组 (Grouping)** | 可将 Transition 按逻辑分组(如移动/战斗/特殊),在编辑器窗口中折叠/展开,大型 Library 组织更清晰 |
| **Normalized Start Time 编辑** | 修正器现可同时覆盖 Fade Duration 和 Normalized Start Time |
| **Edit 按钮** | Inspector 中 `TransitionLibraryAsset` 字段新增 Edit 按钮,一键跳转到 Library 编辑窗口 |
| **改进的 Remove** | Remove Transition 按钮支持单独移除修正器或整个分组 |
### 6.6 其他 Transition 类型
| 类型 | 说明 |
|------|------|
| `ControllerTransition` | 包装 RuntimeAnimatorController |
| `LinearMixerTransition` | 1D 混合(走→跑) |
| `MixerTransition2D` | 2D 混合(八方向移动) |
| `ManualMixerTransition` | 手动权重混合 |
| `PlayableAssetTransition` | Timeline PlayableAsset |
| `TransitionSequence` | 串联多个 Transition |
| `ClipTransitionSequence` | 串联多个 ClipTransition连招 |
### 6.7 FadeMode 枚举
| FadeMode | 行为 | 适用场景 |
|----------|------|---------|
| `FixedSpeed` (默认) | 淡入速度固定,半途开始则更快完成 | 通用默认 |
| `FixedDuration` | 淡入时长固定,不论起始权重 | 需要可预测时长 |
| `FromStart` | 克隆状态从头播放,旧状态同时淡出 | **同动画中断自身**(连续攻击) |
| `NormalizedSpeed` | FixedSpeed × 动画时长 | 与动画长度成比例 |
| `NormalizedDuration` | FixedDuration × 动画时长 | 与动画长度成比例 |
| `NormalizedFromStart` | FromStart × 动画时长 | 与动画长度成比例 |
---
## 7. 事件系统 (Events)
### 7.1 AnimancerEvent 结构
```csharp
public partial struct AnimancerEvent
{
public float normalizedTime; // 触发时间 [0,1]
public Action callback; // 回调委托
// 特殊常量
public const float AlmostOne = 0.99999994f; // 循环动画末尾事件
// 参数化事件
public static void Parametize<T>(Action<T> callback);
public static T GetCurrentParameter<T>();
}
```
### 7.2 AnimancerEvent.Sequence
```csharp
public class Sequence : IEnumerable<AnimancerEvent>
{
int Count { get; }
AnimancerEvent this[int index] { get; set; }
// 末尾事件(一等公民)
ref AnimancerEvent EndEvent { get; }
float NormalizedEndTime { get; set; }
Action OnEnd { get; set; }
// 操作
void Add(float normalizedTime, Action callback);
void Invoke(AnimancerState state);
// ─── v8.3 新增IndexOf 系列 ───
int IndexOf(StringReference name, int startIndex = 0); // 按名称查找
int IndexOfRequired(StringReference name, int startIndex = 0); // 按名称查找(未找到抛异常)
int IndexOf(AnimancerEvent animancerEvent); // 按事件查找
int IndexOf(float normalizedTime); // 按时间查找
int IndexOf(int indexHint, float normalizedTime); // 带提示的按时间查找
}
```
### 7.3 事件绑定模式
**关键 API**: `state.Events(owner)` — 获取/创建绑定到特定 owner 的本地事件副本。
```csharp
// ✅ 推荐写法:幂等事件绑定
AnimancerState state = _Animancer.Play(_Action);
state.Events(this).OnEnd ??= OnActionEnd; // ??= 保证只赋值一次
// ❌ 错误写法:每次重新赋值导致 GC
state.Events(this).OnEnd = OnActionEnd; // 每次新建 delegate
```
`this` 参数的作用:
- 将事件绑定到该组件的生命周期
- 组件销毁时自动清理事件
- 同一 State 可被不同组件绑定不同事件
### 7.4 命名事件系统
```csharp
public class NamedEventDictionary
{
void Register(string name, Action callback);
void Unregister(string name, Action callback);
void Invoke(string name);
}
```
### 7.5 事件调度架构
| 组件 | 职责 |
|------|------|
| `AnimancerEvent.Dispatcher` | 简化事件触发接口 |
| `AnimancerEvent.Invocation` | 执行上下文State、EventIndex、NormalizedTime、FrameID |
| `AnimancerEvent.InvokerFixed` | 固定速度事件触发器 |
| `AnimancerEvent.InvokerDynamic` | 动态速度事件触发器 |
| `AnimancerEvent.Parameter<T>` | 类型安全的参数化事件 |
| `AnimancerEvent.ParameterBoxed` | Object 类型参数事件 |
### 7.6 与 Unity Animation Events 对比
| 特性 | Unity Animation Events | Animancer Events |
|------|----------------------|-----------------|
| 配置方式 | Animation 窗口可视化 | 代码或 Inspector (ClipTransition) |
| 触发精度 | 依赖帧率,可能跳过 | 精确检测时间范围 |
| 回调类型 | 特定签名方法 | 标准 `Action` 委托 |
| 参数传递 | int/float/string/Object | 闭包捕获任意数据 |
| 生命周期 | 绑定到 Clip 资源 | 绑定到 State 实例 |
| End 事件 | 不原生支持 | `OnEnd` 一等公民 |
| 调试性 | 难以调试 | 可断点、可日志 |
---
## 8. Fade 与权重系统
### 8.1 FadeGroup
管理状态间权重淡入淡出的核心类。
```csharp
public class FadeGroup
{
float FadeSpeed { get; set; }
float RemainingFadeTime { get; }
// 自定义缓动
void SetEasing(Func<float, float> easing);
void SetEasing(Easing.Function function);
}
```
### 8.2 自定义 Fade 缓动
```csharp
AnimancerState state = animancer.Play(clip, 0.25f);
// 预设缓动函数
state.FadeGroup.SetEasing(Easing.Sine.InOut);
// 自定义 lambda
state.FadeGroup.SetEasing(t => t * t);
// 支持的预设缓动族:
// Quadratic, Cubic, Quartic, Quintic, Sine,
// Exponential, Circular, Back, Bounce, Elastic
// 每族含 In, Out, InOut 三种
```
### 8.3 NodeWeight
控制单个节点权重更新逻辑,是 FadeGroup 的内部基础。
### 8.4 DontAllowFade
标记组件,阻止 Sprite 动画淡入淡出(像素风不适合渐变):
```csharp
[AddComponentMenu("Animancer/Don't Allow Fade")]
public class DontAllowFade : MonoBehaviour { }
```
### 8.5 MixerChildFade
Mixer 子状态的特殊淡入行为控制。
---
## 9. Mixer 状态 (混合树等价)
Mixer 是 Animancer 中替代 Mecanim Blend Tree 的方案(全部 **Pro-Only**)。
### 9.1 Mixer 类型对照表
| Animancer Mixer | Mecanim Blend Tree | 参数类型 | 说明 |
|-----------------|-------------------|---------|------|
| `LinearMixerState` | 1D Blend | `float` | 按单轴参数线性混合 |
| `CartesianMixerState` | 2D Freeform Cartesian | `Vector2` | 笛卡尔坐标插值 |
| `DirectionalMixerState` | 2D Freeform Directional | `Vector2` | 极坐标梯度带插值 |
| `ManualMixerState` | Direct Blend | 手动权重 | 直接控制每个子状态权重 |
### 9.2 ManualMixerState (手动混合)
```csharp
public class ManualMixerState : ParentState, ICopyable, IParametizedState, IUpdatable
{
// 子状态管理
void Add(AnimancerState state);
void Set(int index, AnimancerState state);
void Remove(AnimancerState state);
void SetChildWeight(int index, float weight);
// 属性
AnimancerState[] ChildStates { get; }
int ChildCount { get; }
float Length { get; } // 加权平均时长
// 同步
void GetSynchronizedChildren(); // 获取同步子集
void RecalculateWeights(); // 重新计算混合权重
}
```
### 9.3 MixerState<T> (参数化混合基类)
```csharp
public abstract class MixerState<T> : ManualMixerState
{
T Parameter { get; set; } // 驱动参数
T NormalizedParameter { get; set; } // 归一化参数
T[] Thresholds { get; } // 阈值数组
// 子类实现
abstract void CalculateWeights(); // 混合权重算法
// 参数绑定
StringReference ParameterName { get; set; } // 绑定到 ParameterDictionary
}
```
### 9.4 LinearMixerState (1D 混合)
```csharp
public class LinearMixerState : MixerState<float>
{
float MinThreshold { get; }
float MaxThreshold { get; }
bool ExtrapolateSpeed { get; set; } // 参数超阈值时自动加速
void Add(AnimancerState state, float threshold);
void AssertThresholdsSorted();
}
```
**用法示例**:
```csharp
[SerializeField] private LinearMixerTransition _moveBlend;
// Inspector 配置: Idle(0) → Walk(0.5) → Run(1.0)
var state = animancer.Play(_moveBlend);
((LinearMixerState)state).Parameter = moveSpeed; // 实时更新
```
### 9.5 Vector2MixerState (2D 混合)
```csharp
public abstract class Vector2MixerState : MixerState<Vector2>
{
float ParameterX { get; set; }
float ParameterY { get; set; }
StringReference ParameterNameX { get; set; }
StringReference ParameterNameY { get; set; }
}
```
**CartesianMixerState** — 笛卡尔坐标插值,适合前进/侧移。
**DirectionalMixerState** — 极坐标梯度带插值(Polar Gradient Band),比 Mecanim 更精确,适合八方向移动。
### 9.6 NodeParameter (参数绑定)
自动将 Mixer 参数同步到全局 `ParameterDictionary`
```csharp
var mixer = new LinearMixerState();
mixer.ParameterName = "Speed";
// 自动绑定到 graph.Parameters["Speed"]
// 外部修改 Parameters["Speed"] 时 mixer 自动重算权重
```
### 9.7 Mixer vs Blend Tree
| 特性 | Mecanim Blend Tree | Animancer Mixer |
|------|-------------------|-----------------|
| 配置方式 | Animator 窗口图形化 | 代码或 Inspector |
| 动态修改 | 不支持运行时修改结构 | 可运行时添加/移除/替换子状态 |
| 嵌套 | 可嵌套 | 可嵌套 |
| 参数驱动 | Animator Parameters | 直接属性或 ParameterDictionary |
| 同步 | 有限 | `TimeSynchronizer` 完整同步 |
| 调试 | 不可视化权重 | Inspector 实时显示 |
---
## 10. 动画层 (Layers)
### 10.1 AnimancerLayer
```csharp
public sealed class AnimancerLayer : AnimancerNode
{
// ─── 状态管理 ───
AnimancerState CurrentState { get; }
IReadOnlyList<AnimancerState> ActiveStates { get; }
// ─── 混合模式 ───
bool IsAdditive { get; set; } // 叠加 vs 覆盖
AvatarMask Mask { get; set; } // 骨骼遮罩
float Weight { get; set; } // 层权重
// ─── IK ───
bool ApplyAnimatorIK { get; set; }
bool ApplyFootIK { get; set; }
// ─── 方法 ───
AnimancerState Play(ITransition transition);
AnimancerState Play(AnimancerState state, float fadeDuration, FadeMode fadeMode);
AnimancerState GetOrCreateState(ITransition transition);
void Stop() / void Pause();
// ─── 查询 ───
int ChildCount { get; }
int CommandCount { get; } // 状态变更计数器
Vector3 AverageVelocity { get; } // 加权平均速度
}
```
### 10.2 AnimancerLayerList
```csharp
public abstract class AnimancerLayerList : IEnumerable<AnimancerLayer>
{
int Count { get; }
static int DefaultCapacity { get; } // 默认 4 层
AnimancerLayer this[int index] { get; } // 自动创建
AnimancerLayer Add();
void SetMinCount(int min);
bool IsAdditive(int index);
void SetAdditive(int index, bool value);
AvatarMask GetMask(int index);
void SetMask(int index, AvatarMask mask);
}
```
### 10.3 Weighted Mask Layers (高级骨骼权重控制)
标准 `AvatarMask` 只能做 0/1 二值遮罩。WeightedMaskLayers 支持**每骨骼浮点权重**
```csharp
[AddComponentMenu("Animancer/Weighted Mask Layers")]
public class WeightedMaskLayers : MonoBehaviour
{
[SerializeField] private AnimancerComponent _Animancer;
[SerializeField] private WeightedMaskLayersDefinition _Definition;
[SerializeField] private int _LayerCount = 2;
}
```
| 组件 | 职责 |
|------|------|
| `WeightedMaskLayers` | 主控组件 |
| `WeightedMaskLayersDefinition` | SO 定义(权重组配置) |
| `WeightedMaskLayerList` | 动态遮罩列表 |
| `WeightedMaskMixerJob` | IAnimationJob 实现逐骨骼混合 |
实现原理:使用 `IAnimationJob` + `NativeArray<float>` 逐骨骼混合权重。
**v8.3 新增 — Root Motion 权重**:每层可独立设置 Root Motion 影响权重,`WeightedMaskLayersDefinition` 新增 `RootMotionWeights` 数组,`WeightedMaskMixerJob` 通过 `NativeArray<float> rootMotionWeights` 逐层混合 Root Motion 输出。适用于上半身覆盖层不影响角色位移的场景。
### 10.4 层使用示例
```csharp
// 基础层(0) — 全身动画
animancer.Layers[0].Play(walkTransition);
// 上半身覆盖层(1) — 边走边射击
animancer.Layers[1].Play(shootTransition);
animancer.Layers[1].Mask = upperBodyMask; // AvatarMask
animancer.Layers[1].Weight = 1f;
animancer.Layers[1].IsAdditive = false; // 覆盖模式
```
---
## 11. Controller State (Mecanim 兼容)
### 11.1 ControllerState (Pro)
包装一个完整的 `RuntimeAnimatorController` 作为 Animancer 图中的一个节点:
```csharp
public class ControllerState : AnimancerState, ICopyable, IParametizedState, IUpdatable
{
RuntimeAnimatorController Controller { get; }
AnimatorControllerPlayable Playable { get; }
// 层管理
int LayerCount { get; }
float GetLayerWeight(int layer) / SetLayerWeight(int, float);
void GetLayerAvatarMask(int) / SetLayerAvatarMask();
// Animator 参数
void SetBool(string, bool) / GetBool();
void SetFloat(string, float) / GetFloat();
void SetInteger(string, int) / GetInteger();
void Trigger(string name);
// 停止行为配置
int[] DefaultStateHashes { get; }
ActionOnStop[] ActionsOnStop { get; }
enum ActionOnStop { DefaultState, RewindTime, Continue }
}
```
### 11.2 ControllerState.ParameterBinding
将 Controller 参数绑定到 Animancer 的 `ParameterDictionary`,双向同步。
---
## 12. 内置有限状态机 (FSM)
Animancer 附带一个**与动画完全独立**的通用 FSM 系统,位于 `Animancer.FSM` 命名空间。
### 12.1 IState 接口
```csharp
public interface IState
{
bool CanEnterState { get; } // 进入守卫
bool CanExitState { get; } // 退出守卫
void OnEnterState(); // 进入回调
void OnExitState(); // 退出回调
}
// 扩展接口 — 状态知道自己属于哪个状态机
public interface IOwnedState<TState> : IState
{
StateMachine<TState> OwnerStateMachine { get; }
}
```
### 12.2 StateMachine\<TState\> (无键状态机)
```csharp
public class StateMachine<TState> where TState : class, IState
{
TState CurrentState { get; }
TState PreviousState { get; }
TState NextState { get; }
// 四种切换策略
bool CanSetState(TState state); // 检查能否切换(两端守卫)
bool TrySetState(TState state); // 尊重守卫,已在该状态则跳过
bool TryResetState(TState state); // 尊重守卫,允许重入自身
void ForceSetState(TState state); // 强制切换(忽略守卫)
// 默认状态支持 (WithDefault 嵌套类)
TState DefaultState { get; set; }
bool TrySetDefaultState();
void ForceSetDefaultState();
}
```
### 12.3 StateMachine\<TKey, TState\> (带键状态机)
```csharp
public class StateMachine<TKey, TState> : StateMachine<TState>
where TState : class, IState
{
TKey CurrentKey { get; }
void Register(TKey key, TState state);
TState GetState(TKey key);
bool TryGetState(TKey key, out TState state);
bool TrySetState(TKey key);
bool TryResetState(TKey key);
void ForceSetState(TKey key);
}
```
### 12.4 StateBehaviour
MonoBehaviour 基类,用 `OnEnable()`/`OnDisable()` 映射状态进出:
```csharp
public abstract class StateBehaviour : MonoBehaviour, IOwnedState
{
// OnEnable() → 进入状态Enable 组件)
// OnDisable() → 退出状态Disable 组件)
public virtual bool CanEnterState => true;
public virtual bool CanExitState => true;
}
```
### 12.5 DelegateState
Lambda 快速创建状态:
```csharp
var state = new DelegateState(
canEnter: () => true,
onEnter: () => Debug.Log("Enter"),
onExit: () => Debug.Log("Exit")
);
```
### 12.6 InputBuffer
解决"动作不可中断时输入会丢失"的问题:
```csharp
public class InputBuffer
{
void Buffer(TState state, float timeout); // 缓冲一个输入
void Update(); // 每帧检查能否执行
// 在 timeout 内反复 TrySetState成功则消耗缓冲
}
```
### 12.7 StateChange / KeyChange
转换上下文结构,在切换过程中提供 `PreviousState`/`NextState` 信息:
```csharp
using (new StateChange<T>(machine, previousState, nextState))
{
previousState.OnExitState();
nextState.OnEnterState();
}
```
### 12.8 FSM 使用架构
```
Character (MonoBehaviour, hub)
├── AnimancerComponent — 动画
├── StateMachine<CharacterState>.WithDefault — 状态机
└── Equipment / HealthPool — 数据
CharacterState (StateBehaviour, 基类)
├── IdleState — 默认状态
├── MoveState — 移动
├── ActionState — 攻击/技能
└── ...
Brain (MonoBehaviour, 输入驱动)
├── PlayerBrain — 玩家输入
└── AIBrain — AI 行为
```
---
## 13. 参数系统 (Parameters)
### 13.1 ParameterDictionary
全局命名参数字典,供 Mixer 自动绑定:
```csharp
// 写入
animancer.Parameters.Set<float>("Speed", 5f);
// 读取
float speed = animancer.Parameters.Get<float>("Speed").Value;
// 尝试读取
if (animancer.Parameters.TryGet<float>("Speed", out var param))
Debug.Log(param.Value);
```
### 13.2 Parameter\<T\>
泛型参数,支持变更事件:
```csharp
public class Parameter<T>
{
T Value { get; set; }
StringReference Key { get; }
Type ValueType { get; }
event Action<T> OnValueChanged;
}
```
### 13.3 SmoothedFloatParameter / SmoothedVector2Parameter
平滑参数,自动插值到目标值:
```csharp
public class SmoothedFloatParameter
{
float TargetValue { get; set; }
float CurrentValue { get; }
void Update(float deltaTime); // 每帧平滑
}
```
### 13.4 StringReference / StringAsset
轻量字符串引用,用于参数键和事件名:
- `StringReference` — 运行时字符串唯一化包装
- `StringAsset` — ScriptableObject 容器,可在 Inspector 中引用
---
## 14. 高级特性
### 14.1 Directional Animations (方向动画)
支持 2D/4D/8D 方向动画集:
```csharp
// 2方向左/右)
[SerializeField] private DirectionalAnimationSet2 _walk2;
// 4方向上/下/左/右)
[SerializeField] private DirectionalAnimationSet4 _walk4;
// 8方向
[SerializeField] private DirectionalAnimationSet8 _walk8;
// 3D 版本(根据 Vector3 方向选择)
[SerializeField] private DirectionalAnimations3D _walk3D;
// 按方向播放
animancer.Play(_walk4.GetClip(facingDirection));
```
### 14.2 Root Motion 重定向
当模型和逻辑在不同 GameObject 时:
| 组件 | 目标类型 | Position | Rotation |
|------|---------|----------|----------|
| `RedirectRootMotionToTransform` | `Transform` | 直接赋值 | 直接赋值 |
| `RedirectRootMotionToRigidbody` | `Rigidbody` | `MovePosition()` | `MoveRotation()` |
| `RedirectRootMotionToCharacterController` | `CharacterController` | `Move(delta)` | 直接赋值 |
基于 `OnAnimatorMove()` 读取 `Animator.deltaPosition/deltaRotation` 后转发。
### 14.3 Sprite 专用功能
| 功能 | 说明 |
|------|------|
| `SpriteRendererTextureSwap` | 运行时替换 Sprite 纹理(换皮) |
| `DontAllowFade` | 禁止 Sprite 动画渐变淡入(像素风) |
### 14.4 TimeSynchronizer
同步多个 Mixer 子状态的播放进度(如走路/跑步脚步对齐)。
### 14.5 ExitEvent
简化"等待动画结束后执行"的模式:
```csharp
var state = animancer.Play(clip);
ExitEvent.Register(state, () => Debug.Log("动画结束"));
```
### 14.6 PlayableOutputRefresher
处理 `Animator` 参数(如 `updateMode`)在运行时变化时的 PlayableOutput 刷新。
### 14.7 Animation Jobs
内置 Animation Job 工具:
| 类 | 功能 |
|----|------|
| `AnimancerJob` | ScriptPlayable 基础 Job |
| `AnimatedBool` | 布尔值动画属性 |
| `AnimatedInt` | 整数动画属性 |
| `AnimatedFloat` | 浮点动画属性 |
| `AnimatedProperty` | 通用属性动画 |
### 14.8 Clone/Deep Copy 系统
通过 `CloneContext` 实现深拷贝,管理引用映射避免重复克隆:
```csharp
// 所有主要类实现 ICopyable<T> / ICloneable<T>
var clonedState = state.Clone(cloneContext);
```
---
## 15. Editor 工具链
### 15.1 Inspector 调试面板
AnimancerComponent 在运行时提供强大的 Inspector 面板:
- **实时查看**所有层、所有状态的权重、时间、速度
- **直接修改**运行中的状态属性(时间滑块、速度、权重)
- **播放/暂停**单个状态
- 显示 FadeGroup 进度
### 15.2 Transition 预览
在 Inspector 中选中 ClipTransition 字段时:
- **编辑模式预览**动画效果
- 可视化事件时间轴
- 拖拽调整事件位置
### 15.3 Animancer Tools 窗口
`Window → Animation → Animancer Tools`
| 工具 | 功能 |
|------|------|
| `AnimancerSettingsTool` | 全局设置 |
| `GenerateSpriteAnimationsTool` | 从 Sprite Sheet 生成 Clip |
| `PackTexturesTool` | 纹理打包 |
| `ModifySpritesTool` | 批量修改 Sprite 属性 |
| `RenameSpritesTool` | 批量重命名 |
| `RemapAnimationBindingsTool` | 重映射动画绑定路径 |
| `RemapSpriteAnimationTool` | 重映射 Sprite 动画 |
| `AnimationModifierTool` | 修改 Clip 属性 |
| `SpriteDataEditor` | Sprite 数据编辑 |
### 15.4 TransitionAsset Generator
从 AnimationClip 右键菜单直接生成 TransitionAsset。
### 15.5 Transition Library Editor (Pro)
可视化编辑 TransitionLibraryAsset为每对 (from, to) 转换定义 Modifier。
**v8.3 编辑器改进**
- Inspector 中 `TransitionLibraryAsset` 字段增加 **Edit** 按钮,一键打开 Library 编辑窗口
- Fade Duration / Start Time 显示更紧凑清晰
- 支持 **Transition 分组**:按语义分类(移动/战斗/特殊等),折叠展开大型 Library
- Remove 按钮支持单独移除修正器或整个分组
---
## 16. 数据类型与工具
### 16.1 对象池
| 类 | 功能 |
|----|------|
| `ObjectPool<T>` | 泛型对象池 |
| `ListPool<T>` | List 池 |
| `DictionaryPool<K,V>` | Dictionary 池 |
| `SetPool<T>` | HashSet 池 |
| `CollectionPool<T>` | ICollection 池 |
| `StringBuilderPool` | StringBuilder 池 |
### 16.2 工具类
| 类 | 功能 |
|----|------|
| `FastEnumerator<T>` | 高性能枚举器 |
| `IndexedList<T>` | 带索引的列表 |
| `Updatable.List` | 可更新对象列表 + 调度 |
| `AnimancerUtilities` | 连接/断开 Playable 等扩展方法 |
### 16.3 接口体系 (16 个)
| 接口 | 用途 |
|------|------|
| `IAnimancerComponent` | 组件契约 |
| `ITransition` / `ITransition<T>` | 状态创建和配置 |
| `IState` | FSM 状态 |
| `IMotion` | Root Motion 数据 |
| `IUpdatable` | 自定义帧更新 |
| `IHasKey` | 键属性 |
| `IHasEvents` | 事件属性 |
| `IHasDescription` | 描述/ToString |
| `ICloneable<T>` / `ICopyable<T>` | 克隆/深拷贝 |
| `IConvertable<T>` | 类型转换 |
| `IPolymorphic` | 序列化多态 |
| `IWrapper` | 包装对象访问 |
| `ICharacterRoot` | 角色 Root Motion |
| `IInitializable` | 初始化回调 |
| `IInvokable` | 可调用接口 |
| `IAnimationClipCollection` | 动画片段收集 |
---
## 17. Animancer vs Unity Mecanim 详细对比
### 17.1 开发工作流
| 维度 | Mecanim | Animancer |
|------|---------|-----------|
| **播放一个动画** | 创建 Controller → State → Clip → Parameter → Transition → SetTrigger | `animancer.Play(clip)` |
| **配置文件** | 每角色独立 .controller 资产 | 无需额外资产(可选 TransitionAsset |
| **状态管理** | Animator Controller 状态图 | C# 代码(可选内置 FSM |
| **参数传递** | SetFloat/SetBool (魔法字符串) | 直接引用 Clip/Transition |
| **转换条件** | Transition 条件面板 | C# `if/else` |
| **混合树** | Blend Tree 图形化配置 | MixerState 代码/Inspector |
| **动画层** | Layer 面板 | `animancer.Layers[i]` |
| **事件** | Animation Events | AnimancerEvent + Action |
| **调试** | 可看状态图但不可改 | 实时修改所有属性 |
### 17.2 功能矩阵
| 功能 | Mecanim | Animancer Pro |
|------|---------|---------------|
| 播放 Generic/Humanoid/Sprite | ✅ | ✅ |
| Humanoid Retargeting | ✅ | ✅ |
| Humanoid IK | ✅ | ✅ |
| Target Matching | ✅ | ❌ |
| 运行时创建 Clip | ❌ | ✅ |
| 无需 Animator Controller | ❌ | ✅ |
| 无魔法字符串 | ❌ | ✅ |
| 编辑模式动画预览 | ❌ | ✅ |
| 动态 Speed/Time/Weight | 有限 | ✅ 完全 |
| 自定义事件系统 | ❌ | ✅ |
| 自定义 Fade 曲线 | ❌ | ✅ |
| 混合多 Controller | ❌ | ✅ |
| Timeline 混合 | 有限 | ✅ |
| Animation Jobs | ✅ | ✅ |
| FSM | ❌ | ✅ |
| 可视化状态机编辑器 | ✅ | ❌ |
| 源码可访问 | ❌ | ✅ |
### 17.3 Animancer 十大优势
1. **开发效率** — 移除 Animator Controller 中间层
2. **代码即文档** — 动画需求在 Inspector 字段中一目了然
3. **类型安全** — 编译时检查,无魔法字符串
4. **完全可控** — Speed、Time、Weight 任意时刻可读写
5. **事件系统** — 基于 Action 委托,精确且灵活
6. **可组合性** — 每个脚本独立管理动画
7. **调试体验** — 运行时 Inspector 实时可视化和修改
8. **渐进式迁移** — HybridAnimancerComponent 可与现有 Controller 共存
9. **数据驱动** — Transition 系统将参数从代码中分离
10. **源码可用** — 可调试、可修改
### 17.4 Animancer 劣势
1. **无可视化状态机编辑器** — 不适合不写代码的动画师独立工作
2. **学习曲线** — 需从 Mecanim 心智模型转换
3. **第三方依赖** — 插件维护风险
4. **Target Matching 缺失** — Humanoid Target Matching 不支持
5. **社区规模** — 相比 Mecanim 较小
6. **Pro 价格** — 核心功能需要 $90
---
## 18. 性能分析
### 18.1 基准测试结果
| 测试项 | 结果 |
|--------|------|
| **实例化** | Animancer ≈ Mecanim按需初始化可快 20-35% |
| **平均帧率** | Animancer 比 Mecanim 快 ~5%(所有 Rig 类型) |
| **内存** | 基本一致(都基于 PlayableGraph |
### 18.2 核心优化选项
| 选项 | 说明 |
|------|------|
| `KeepChildrenConnected = false` (默认) | 权重归零时断开 Playable 节点,避免评估不可见动画 |
| `KeepChildrenConnected = true` | 适用于 Sprite 动画(连接/断开开销 > 评估开销) |
| 按需初始化 | 不预创建所有 State首次播放时才初始化 |
### 18.3 设计模式带来的性能优势
| 模式 | 说明 |
|------|------|
| **惰性初始化** | Graph、Parameters、Events 均按需创建 |
| **权重断开** | 不可见 Playable 自动断开GPU 零评估开销 |
| **对象池** | 内置 ObjectPool、ListPool 等减少 GC |
| **IUpdatable 调度** | PreUpdate/PostUpdate 列表精确控制更新顺序 |
| **状态注册表** | O(1) 查找已有状态,避免重复创建 |
### 18.4 限制与注意事项
| 限制 | 说明 |
|------|------|
| AnimatePhysics 模式 | 不能运行时切换 |
| ControllerState 事件 | 对所有 Controller 层触发(非单独) |
| PlayableAssetState | 不支持动态 IK |
| 默认最多 4 层 | 可通过 `DefaultCapacity` 扩展 |
| IK 仅限 ClipState | Mixer/ParentState 不支持 |
| 循环动画事件 | NormalizedTime 必须 < 1.0 |
---
## 19. 与 BaseGames 架构集成方案
### 19.1 项目定位
根据 BaseGames 架构文档(`08_Physics_Animation.md` §6
> **项目采用 Animancer Pro 作为唯一动画方案,完全替代 Unity Animator Controller。**
Animancer 是项目的**核心运行时依赖**,用于所有角色动画驱动。
### 19.2 ActorCore 中的引用
```csharp
public sealed class ActorCore : MonoBehaviour
{
public AnimancerComponent Animancer { get; private set; }
private void Awake()
{
Animancer = GetComponentInChildren<AnimancerComponent>();
}
}
```
所有子系统通过 `ActorCore.Animancer` 访问动画。
### 19.3 AbilityTask 集成 — PlayAnimationTask
`PlayAnimationTask` 是技能系统中使用最频繁的 Task直接调用 Animancer API
```csharp
[Serializable]
public sealed class PlayAnimationTask : IAbilityTask
{
public TransitionAsset Animation;
public bool WaitForCompletion = true;
private AnimancerState _state;
private bool _ended;
public void Begin(AbilityContext ctx)
{
_ended = false;
_state = ctx.Animancer.Play(Animation);
if (WaitForCompletion)
_state.Events(this).OnEnd ??= () => _ended = true;
}
public bool Tick(AbilityContext ctx, float deltaTime)
=> !WaitForCompletion || _ended;
public void End(AbilityContext ctx) { }
}
```
**关键要点**
- 使用 `TransitionAsset` (SO) 实现数据驱动AbilityDefSO 直接引用动画配置
- `Events(this).OnEnd ??=` 幂等注册,防止重复绑定
- `WaitForCompletion` 控制是否阻塞后续 Task
### 19.4 技能编排示例 — 三段连击
```yaml
Ability: "三段普攻"
Phase1:
- PlayAnimation: TA_Attack_1_Windup
- ActivateHitbox: { Duration: 0.1 }
- PlayAnimation: TA_Attack_1_Strike
- ApplyDamage: { Tag: Melee, Multiplier: 1.0 }
- PlayAnimation: TA_Attack_1_End
Phase2:
- PlayAnimation: TA_Attack_2_Windup
- ActivateHitbox: { Duration: 0.15 }
- PlayAnimation: TA_Attack_2_Strike
- ApplyDamage: { Tag: Melee, Multiplier: 1.2 }
- PlayAnimation: TA_Attack_2_End
Phase3:
- PlayAnimation: TA_Attack_3_Windup
- ActivateHitbox: { Duration: 0.2 }
- PlayAnimation: TA_Attack_3_Strike
- ApplyDamage: { Tag: Melee, Multiplier: 1.5 }
- PlayAnimation: TA_Attack_3_End
```
每个 `TA_*` 都是一个 `TransitionAsset`,包含 Clip、FadeDuration、Speed、Events。
### 19.5 Cinematic 系统集成
```csharp
public sealed class PlayAnimAction : ICinematicAction
{
public TransitionAsset Animation;
public bool WaitForComplete = true;
public bool Execute(CinematicContext ctx)
{
if (_animancer == null)
{
var actor = ctx.CinematicRoot.Find(ActorTag);
_animancer = actor?.GetComponent<AnimancerComponent>();
_state = _animancer.Play(Animation);
if (WaitForComplete)
_state.Events(this).OnEnd ??= () => _ended = true;
}
return !WaitForComplete || _ended;
}
}
```
### 19.6 移动混合 — 替代 Blend Tree
```csharp
[SerializeField] private LinearMixerTransition _moveBlend;
// Inspector 配置: Idle(0) → Walk(0.5) → Run(1.0)
var state = animancer.Play(_moveBlend);
((LinearMixerState)state).Parameter = currentSpeed;
```
### 19.7 Transition 层级选择指南
| 场景 | 推荐级别 | 理由 |
|------|---------|------|
| 原型开发 / 临时动画 | Level 0 `AnimationClip` | 最快速 |
| 单脚本专用动画 | Level 1 `ClipTransition` | Inspector 可配置 |
| AbilityDefSO 引用 | Level 2 `TransitionAsset` | 跨技能/跨角色共享 |
| 形态切换时全套动画 | Level 3 `TransitionLibrary` | 集中管理 + 转换修正器 |
### 19.8 FSM 集成指南
Animancer 自带 FSM 与 BaseGames 的 GAS-lite 技能系统存在职责划分:
| 场景 | 推荐方案 |
|------|---------|
| **技能/Ability 状态管理** | BaseGames `GameplayAbilitySystem` |
| **角色基础状态 (Idle/Move/Jump/Fall)** | Animancer FSM 或自有系统 |
| **纯动画逻辑 (连段内部)** | Animancer FSM + `InputBuffer` |
| **AI 行为树** | Behavior Designer |
### 19.9 迁移路径
```
Phase 1: 新代码直接使用 Animancer
Phase 2: 已有动画通过 HybridAnimancerComponent 兼容
Phase 3: 逐步将 Animator Controller 逻辑迁移为纯 Animancer
Phase 4: 移除所有 Animator Controller 资产
```
### 19.10 架构适配速查表
| 架构组件 | 设计 | 说明 |
|---------|------|------|
| `ActorCore.Animancer` | `AnimancerComponent` 引用 | 所有系统的动画入口 |
| `PlayAnimationTask` | `TransitionAsset` + `Events(this).OnEnd` | 技能驱动动画 |
| `PlayAnimAction` | 同上 | 过场动画驱动 |
| `AbilityDefSO` | 持有多个 `TransitionAsset` 字段 | 数据驱动动画配置 |
| 移动混合 | `LinearMixerTransition` | 替代 Blend Tree |
| 动画事件 | `AnimancerEvent.Sequence` | 替代 Animation Events |
---
## 20. 优缺点总结
### 20.1 技术评分
| 维度 | 评分 (1-10) | 说明 |
|------|-------------|------|
| 功能完整度 | **9** | 覆盖 State/Layer/Mixer/Events/FSM/Jobs/Timeline |
| API 设计 | **9** | 极简 Play() 入口 + 丰富的配置层级 |
| 文档质量 | **9** | 官方文档详尽,示例场景 10 组 |
| 性能 | **8** | 与 Mecanim 一致或略优,权重断开优化 |
| 易用性 | **9** | 一行代码上手Inspector 友好 |
| 可维护性 | **8** | 171 文件、完整源码、Partial 组织清晰 |
| 与项目契合度 | **10** | 架构核心依赖,完全适配 GAS-lite 设计 |
| **综合** | **9.0** | 项目核心动画方案,完全替代 Mecanim |
### 20.2 核心优势
| 优势 | 说明 |
|------|------|
| **代码驱动** | 与 GAS-lite "代码驱动一切" 理念完全一致 |
| **数据驱动** | TransitionAsset → SO → AbilityDefSO完美数据管线 |
| **类型安全** | 无魔法字符串,编译时安全 |
| **事件一等公民** | `OnEnd` 直接解决动画结束通知最大痛点 |
| **调试体验** | 运行时 Inspector 实时可视化 |
| **完整源码** | 可调试可修改可学习 |
| **渐进迁移** | Hybrid 组件平滑过渡 |
| **Sprite 优化** | 像素风专用优化 (DontAllowFade, KeepChildrenConnected) |
### 20.3 风险与缓解
| 风险 | 缓解方案 |
|------|---------|
| 第三方依赖 | Pro 版有完整源码,可自行维护 |
| 无 Target Matching | 项目为 2D不需要此功能 |
| 无可视化编辑器 | 策划通过 TransitionAsset Inspector 配置 |
---
## 21. 总结与建议
### 21.1 总体评价
Animancer Pro v8.3.0 是 Unity 生态中**最成熟的代码驱动动画方案**。对于 BaseGames 这一 2D Metroidvania 项目:
1. **核心动画引擎** — 已作为唯一动画方案深度集成
2. **与技能系统无缝配合** — TransitionAsset + PlayAnimationTask 构成完整数据管线
3. **性能可靠** — 权重断开/惰性初始化/对象池等优化到位
4. **Sprite 友好** — DontAllowFade/KeepChildrenConnected/SpriteRendererTextureSwap
5. **v8.3 增强** — TransitionLibrary 分组/TryGetAlias 别名查找/Event.Sequence.IndexOf/WeightedMaskLayers Root Motion 权重
### 21.2 最佳实践
| 实践 | 建议 |
|------|------|
| **事件绑定** | 始终使用 `Events(this).OnEnd ??=` 幂等模式 |
| **Transition 选择** | AbilityDefSO 用 TransitionAsset脚本内用 ClipTransition |
| **FadeMode** | 连击用 `FromStart`,通用用 `FixedSpeed` |
| **Sprite 动画** | 设置 `KeepChildrenConnected = true` 减少连接开销 |
| **性能模式** | 生产版本不影响Inspector 开销仅编辑器) |
| **层管理** | Layer 0 全身Layer 1+ 覆盖层(上半身/表情) |
| **参数绑定** | Mixer 使用 `ParameterName` 自动绑定到 ParameterDictionary |
### 21.3 关键文件速查
| 用途 | 类名 | 路径 |
|------|------|------|
| 主组件 | `AnimancerComponent` | `Runtime/AnimancerComponent.cs` |
| 核心图 | `AnimancerGraph` | `Runtime/Core/AnimancerGraph.cs` |
| 片段状态 | `ClipState` | `Runtime/Core/Nodes/ClipState.cs` |
| 动画层 | `AnimancerLayer` | `Runtime/Core/Nodes/AnimancerLayer.cs` |
| 事件 | `AnimancerEvent` | `Runtime/Core/Events/AnimancerEvent.cs` |
| 事件序列 | `AnimancerEvent.Sequence` | `Runtime/Core/Events/AnimancerEvent.Sequence.cs` |
| 淡入淡出 | `FadeGroup` | `Runtime/Core/Fades/FadeGroup.cs` |
| Transition 接口 | `ITransition` | `Runtime/Interfaces/ITransition.cs` |
| ClipTransition | `ClipTransition` | `Runtime/Utilities/Transitions/Transition Types/ClipTransition.cs` |
| TransitionAsset | `TransitionAsset` | `Runtime/Utilities/Transitions/TransitionAsset.cs` |
| TransitionLibrary | `TransitionLibraryAsset` | `Runtime/Utilities/Transitions/Transition Libraries/TransitionLibraryAsset.cs` |
| 线性混合 | `LinearMixerState` | `Runtime/Mixer States/LinearMixerState.cs` |
| 方向混合 | `DirectionalMixerState` | `Runtime/Mixer States/DirectionalMixerState.cs` |
| Controller 状态 | `ControllerState` | `Runtime/Controller States/ControllerState.cs` |
| FSM | `StateMachine<T>` | `Runtime/Utilities/FSM/StateMachine1.cs` |
| IState | `IState` | `Runtime/Utilities/FSM/IState.cs` |
| 输入缓冲 | `InputBuffer` | `Runtime/Utilities/FSM/StateMachine1.InputBuffer.cs` |
| 缓动 | `Easing` | `Runtime/Utilities/Custom Fade/Easing.cs` |
| Root Motion | `RedirectRootMotion*` | `Runtime/Utilities/Redirect Root Motion/` |
| Weighted Mask | `WeightedMaskLayers` | `Runtime/Core/Weighted Mask Layers/WeightedMaskLayers.cs` |
| 参数字典 | `ParameterDictionary` | `Runtime/Data Types/Parameters/ParameterDictionary.cs` |
| 方向动画 | `DirectionalAnimationSet*` | `Runtime/Utilities/Directional Animations/` |
| 对象池 | `ObjectPool<T>` | `Runtime/Data Types/Object Pooling/ObjectPool.cs` |
---
> **文档版本**: 1.1
> **基于**: Animancer Pro v8.3.0 源码分析 (171 个源文件) + 官方文档 + BaseGames 架构文档
> **源文档**: `Docs/Guides/Animancer_Technical_Evaluation.md`
> **架构参考**: `Docs/Architecture/08_Physics_Animation.md` §6、`05_Ability_System.md` §5、`18_Cinematic_System.md`