动画节点技术指南

指南,说明如何创建在动画蓝图图表中使用的新节点。

Windows
MacOS
Linux

动画蓝图 中需要用到动画节点 来执行姿势混合或骨骼直接操纵等运算。引擎提供多个动画 节点,但你也可以创建自定义节点,以满足任意游戏的需求。

动画节点解析

动画节点由两部分构成:

  • 执行实际运算以生成输出姿势的运行时结构体。

  • 处理节点在图表中的视觉特征和功能(例如,节点标题和情境菜单) 的编辑器时容器类。

要添加新动画节点,必须创建这两个部分。

节点层级

你可以创建节点层级,但任何非抽象编辑器时类都应仅包含 一个运行时节点(派生时请勿添加额外节点,除非父项为抽象类,未包含运行时节点)。
请参阅 UAnimGraphNode_BlendListBase 系列,以查看示例。

运行时节点

该运行时结构体派生自 FAnimNode_Base,负责初值设定、更新和 针对一个或多个输入姿势执行运算以生成所需输出姿势。它也会声明 节点执行所需运算所需的所有输入姿势链接和所有属性。

姿势输入

节点可具有单个姿势输入:

本地空间

UPROPERTY(Category=Links)
FPoseLink BasePose;

Pose Input Pin

组件空间

UPROPERTY(Category=Links)
FComponentSpacePoseLink ComponentPose;

Pose Input Pins

组件空间姿势引脚为蓝色。

在多个动画间混合的节点可具有多个输入:

UPROPERTY(Category=Links)
FPoseLink Base;

UPROPERTY(Category=Links)
FPoseLink Additive;

Pose Input Pins

这些属性中的每个属性都会使一个姿势链接显示。此类型的属性始终作为输入引脚 公开。无法选择将它们隐藏或仅作为 细节(Details) 面板中的可编辑属性使用。

属性和数据输入

动画节点可具有任意数量的可用于执行节点运算的属性, 例如,阿尔法(Alpha)或变换数据。声明这些属性的方法与声明任何其他属性的方法相同,都是使用 UPROPERTY 宏。

UPROPERTY(Category=Settings, meta(PinShownByDefault))
mutable float Alpha;

Property Pin

可使用特殊元数据键将动画节点的属性作为数据输入公开,以允许值 传入节点。这使节点使用的属性能够使用在节点之外计算的数值。 提供下列元数据键:

元数据

说明

NeverAsPin

该属性未作为数据引脚公开,仅可在Persona中的 细节(Details) 面板中编辑。

PinHiddenByDefault

该属性可作为数据引脚公开,但默认被隐藏(请参阅下面的 可选引脚 )。

PinShownByDefault

该属性可作为数据引脚公开,默认可见(请参阅下面的 可选引脚 )。

AlwaysAsPin

该属性始终作为数据引脚公开。

可选引脚

对于具有 PinHiddenByDefaultPinShownByDefault 元数据键的属性, 在 细节(Details) 面板中,其Alpha属性旁边显示有眼睛图标,允许你选择显示或隐藏它。

Property Details

编辑器节点

该编辑器类派生自 UAnimGraphNode_Base,负责可见节点 标题或情境菜单操作添加等。

该编辑器时类应包含作为"可编辑"公开的运行时节点的一个实例。

UPROPERTY(Category=Settings)
FAnimNode_ApplyAdditive Node;

标题

Node Title

定义在Persona中的动画蓝图图表中显示的动画节点的标题的背景颜色和文本的方法是 覆盖 GetNodeTitleGetNodeTitleColor 函数。

例如,UAnimGraphNode_ApplyAdditive 节点使用灰色背景并且显示为"应用Additive(Apply Additive)":

FLinearColor UAnimGraphNode_ApplyAdditive::GetNodeTitleColor() const
{
    return FLinearColor(0.75f, 0.75f, 0.75f);
}

FString UAnimGraphNode_ApplyAdditive::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
    return TEXT("Apply Additive");
}

提示文本

Node Tooltip

定义在Persona中将鼠标悬停在节点上时显示的提示文本的方法是覆盖 GetTooltip 函数:

FString UAnimGraphNode_ApplyAdditive::GetTooltip const
{
    return TEXT("Apply additive animation to normal pose");
}

情境菜单

每个动画节点都可向情境菜单(在Persona中 右键单击 图表中的节点时显示) 中添加节点特定的选项。这些选项是使用 GetContextMenuActions 函数添加的,它是 所有蓝图节点的成员。

Node Context Menu Entry

例如,UAnimGraphNode_LayeredBoneBlend 节点会添加适用于添加新输入或删除现有输入的菜单项:

void UAnimGraphNode_LayeredBoneBlend::GetContextMenuActions(const FGraphNodeContextMenuBuilder& Context) const
{
    if (!Context.bIsDebugging)
    {
        if (Context.Pin != NULL)
        {
            // 我们仅为常规混合列表(BlendList)/按枚举混合列表(BlendList)实现此函数,按布尔混合列表(BlendList)不支持添加/删除引脚
            if (Context.Pin->Direction == EGPD_Input)
            {
                //@TODO:仅在具有数组的引脚上提供此选项
                Context.MenuBuilder->BeginSection("AnimNodesLayeredBoneBlend", NSLOCTEXT("A3Nodes", "LayeredBoneBlend", "Layered Bone Blend"));
                {
                    Context.MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().RemoveBlendListPin);
                }
                Context.MenuBuilder->EndSection();
            }
        }
        else
        {
            Context.MenuBuilder->BeginSection("AnimNodesLayeredBoneBlend", NSLOCTEXT("A3Nodes", "LayeredBoneBlend", "Layered Bone Blend"));
            {
                Context.MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().AddBlendListPin);
            }
            Context.MenuBuilder->EndSection();
        }
    }
}

派生的本机Getter

许多项目中都创建了其自己的 UAnimInstance 派生类,以获得更好的性能。为提供支持,你可在需要时添加新Getter。为此,需要进行一些设置,以使它们正常发挥作用。

  • Getter函数必须标记为 UFUNCTIONS

  • 它们必须是 BlueprintPure

  • 它们必须包含 AnimGetter="True" 元数据。

它们还必须定义一些专门指定的参数(也在 AnimInstance.h 中的基本动画Getter函数上面对它进行了介绍)。这些参数包括:

参数

说明

int32 AssetPlayerIndex

该Getter处理资源播放器,将按可用资源播放器将条目添加到编辑器。

int32 MachineIndex

该Getter处理状态机,将按状态机添加条目。

int32 StateIndex

它还需要MachineIndex。该Getter处理状态,将按状态添加条目。

int32 TransitionIndex

它还需要MachineIndex。该Getter处理过渡,将按过渡添加条目。

也存在帮助程序函数,可获取Getter中的实际节点。它们存在于 UAnimInstance 上:

函数

说明

GetStateMachineInstance(int32 MachineIndex)

获取烘焙后的状态机实例。

GetCheckedNodeFromIndex(int32 NodeIdx)

从索引获取节点,如无效则断言。

GetNodeFromIndex(int32 NodeIdx)

同上,可返回nullptr。

GetRelevantAssetPlayerFromState(int32 MachineIndex, int32 StateIndex)

获取状态中具有最高权重的资源播放器。

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback