AnimNode Skeletal Control Base
August 25, 2024About 4 min
AnimNode Skeletal Control Base
FAnimNode_SkeletalControlBase
是 Unreal Engine 动画蓝图(AnimBlueprint)中用于 骨骼变换控制(Skeletal Control) 的核心基类,所有基于骨骼的动画控制节点(如 ModifyBone
、LookAt
、SpringBone
)都继承自它。它的核心作用是 在动画蓝图的 AnimGraph 中动态修改骨骼的 Transform(位置、旋转、缩放),常用于 IK(逆向动力学)、物理模拟(如布料、头发)、程序化动画调整等场景。
简单例子:

FAnimNode_SkeletalControlBase 的核心作用
主要功能
- 动态修改骨骼 Transform:允许在运行时通过代码调整骨骼的位置(
Location
)、旋转(Rotation
)和缩放(Scale
)。 - 基于 Component Space(组件空间)计算:所有骨骼变换都是在 组件空间(Component Space) 下计算的,确保层级关系正确。
- 支持 LOD(细节级别):可以基于 LOD 级别决定是否执行该节点,优化性能。
- 可调试性:提供
GatherDebugData()
方法,方便在动画蓝图中调试节点效果。
适用场景
- IK(逆向动力学):如
AnimNode_Fabrik
(FABRIK IK 求解器)就是基于它实现的。 - 物理模拟:如
AnimNode_SpringBone
(弹簧骨骼)用于模拟头发、尾巴的物理摆动。 - 程序化动画调整:如
AnimNode_ModifyBone
直接修改骨骼 Transform。 - LookAt 控制:
AnimNode_LookAt
让角色眼睛/头部跟随目标。
FAnimNode_SkeletalControlBase 的核心代码解析
关键方法
EvaluateSkeletalControl_AnyThread()
(必须实现)
virtual void EvaluateSkeletalControl_AnyThread(
FComponentSpacePoseContext& Output,
TArray<FBoneTransform>& OutBoneTransforms
) = 0;
- 作用:核心计算函数,所有骨骼控制逻辑都在这里实现。
- 参数:
Output
:输入动画姿势(Component Space)。OutBoneTransforms
:输出要修改的骨骼变换列表。
- 调用时机:在动画线程(AnimGraph 计算时)执行。
UpdateInternal()
void UpdateInternal(const FAnimationUpdateContext& Context);
- 作用:
- 处理 LOD 判断(
IsLODEnabled()
)。 - 计算
Alpha
(混合权重)是否生效。 - 调用
PreUpdate()
(可被子类覆盖,用于预处理)。
- 处理 LOD 判断(
GatherDebugData()
virtual void GatherDebugData(FNodeDebugData& DebugData);
- 作用:收集调试信息,在动画蓝图的 Debug 模式 下显示节点状态。
关键数据成员
成员变量 | 作用 |
---|---|
FBoneReference BoneToModify | 要控制的骨骼引用 |
FAlphaBlend Alpha | 控制节点的影响权重(0~1) |
FInputAlphaBoolBlend AlphaBoolBlend | 用布尔值控制是否生效 |
int32 LODThreshold | 低于该 LOD 级别时禁用节点 |
工作流程
FAnimNode_SkeletalControlBase
在 AnimGraph 中的执行顺序如下:
初始化阶段(
Initialize_AnyThread
):- 解析骨骼引用(
BoneToModify.Initialize()
)。 - 缓存必要的骨骼索引。
- 解析骨骼引用(
更新阶段(
Update_AnyThread
):- 调用
UpdateInternal()
计算是否要执行(LOD + Alpha 判断)。 - 如果启用,则进入
Evaluate
阶段。
- 调用
评估阶段(
EvaluateComponentSpace_AnyThread
):- 调用
EvaluateSkeletalControl_AnyThread()
计算骨骼变换。 - 将结果写入
FComponentSpacePoseContext
。
- 调用
应用阶段(
EvaluateComponentSpace
):- 最终变换会合并到 Component Space Pose 中。
如何自定义骨骼控制节点?
继承 FAnimNode_SkeletalControlBase
USTRUCT()
struct MYANIMATION_API FAnimNode_MyCustomControl : public FAnimNode_SkeletalControlBase
{
GENERATED_BODY()
// 要控制的骨骼
UPROPERTY(EditAnywhere, Category = "Settings")
FBoneReference TargetBone;
// 自定义参数
UPROPERTY(EditAnywhere, Category = "Settings")
float Strength = 1.0f;
// 必须实现的核心计算函数
virtual void EvaluateSkeletalControl_AnyThread(
FComponentSpacePoseContext& Output,
TArray<FBoneTransform>& OutBoneTransforms
) override;
};
实现 EvaluateSkeletalControl_AnyThread
void FAnimNode_MyCustomControl::EvaluateSkeletalControl_AnyThread(
FComponentSpacePoseContext& Output,
TArray<FBoneTransform>& OutBoneTransforms
)
{
// 1. 获取当前骨骼的 Component Space Transform
const FCompactPoseBoneIndex BoneIndex = TargetBone.GetCompactPoseIndex(Output.Pose.GetPose().GetBoneContainer());
FTransform BoneTransform = Output.Pose.GetComponentSpaceTransform(BoneIndex);
// 2. 修改 Transform(示例:让骨骼沿X轴偏移)
BoneTransform.AddToTranslation(FVector(Strength, 0.f, 0.f));
// 3. 写入输出
OutBoneTransforms.Add(FBoneTransform(BoneIndex, BoneTransform));
}
性能优化建议
- 减少骨骼计算量:
- 只计算必要的骨骼,避免遍历整个骨骼树。
- 合理使用 LOD:
- 高 LOD 时才启用复杂计算(如
LODThreshold = 1
)。
- 高 LOD 时才启用复杂计算(如
- 缓存骨骼索引:
- 在
Initialize_AnyThread
中缓存BoneIndex
,避免运行时查找。
- 在
- 避免频繁内存分配:
- 尽量复用
TArray<FBoneTransform>
,而不是每次Evaluate
都Add
。 - 使用
UE_DONT_INLINE_CALL
调用方法,减少栈使用
- 尽量复用
实际案例:实现一个简单的 "Bone Wiggle" 抖动效果
// 在 EvaluateSkeletalControl_AnyThread 中加入抖动逻辑
void FAnimNode_BoneWiggle::EvaluateSkeletalControl_AnyThread(...)
{
const float Time = GetWorld()->GetTimeSeconds();
const float WiggleOffset = FMath::Sin(Time * Speed) * Intensity;
FTransform BoneTransform = Output.Pose.GetComponentSpaceTransform(BoneIndex);
BoneTransform.AddToTranslation(FVector(0.f, 0.f, WiggleOffset));
OutBoneTransforms.Add(FBoneTransform(BoneIndex, BoneTransform));
}
- 效果:骨骼会沿着 Z 轴上下抖动,可用于呼吸、颤抖等动画增强。
总结
特性 | 说明 |
---|---|
核心用途 | 动态修改骨骼 Transform |
计算空间 | Component Space(组件空间) |
关键方法 | EvaluateSkeletalControl_AnyThread() |
适用场景 | IK、物理模拟、程序化动画 |
性能优化 | LOD + 骨骼索引缓存 |
FAnimNode_SkeletalControlBase
是 UE 动画系统中 最强大的骨骼控制工具之一,掌握它可以实现高度动态、程序化的动画效果。