Skip to main content

Lyra浅析

· 2 min read

角色动画

蓝图结构

TODO: lyra其实把Weapon给单独拿出来了,WeaponInstance中有个PickBestAnimLayer函数,来进行AnimLayer的绑定,这里是简化的描述 alt text

首先,ALI_ItemAnimLayers是一个抽象接口,在这里定义一些子AnimGraph alt text 这些AnimGraph由ABP_ItemAnimLayersBase来实现,比如FullBodyIdleState的实现 alt text

ABP_Mannequin_Base是主蓝图,会包含ALI_ItemAnimLayers接口中的所有子AnimGraph, 需要通过这里来设置 alt text 并会使用到这些AnimGraph的output pose,但只会作为插槽一样的存在,比如 alt text 而子蓝图具体实现在ABP_ItemAnimLayersBase,暴露了一些可配置的参数,比如Idle采用的具体动画序列,在不同状态下是不同的(手枪/步枪/unarmed),这个会在运行时根据逻辑去选择(装配)

猜测一个大概的cpp实现是这样

struct ALI_ItemAnimLayers{
std::function<Pose()> FullBodyIdleState;
std::function<Pose()> FullBodyCycleState;
...
}

struct ABP_ItemAnimLayersBase : public ALI_ItemAnimLayers{

ABP_ItemAnimLayersBase(Config config){
FullBodyIdleState = [](){
...
Sequence seq = Load(config.sequencePath)
return Pose(seq);
}

FullBodyCycleState = [](){
...
Sequence seq = Load(config.sequencePath)
return Pose(seq);
}
}

}

struct ABP_Mannequin_Base{
ALI_ItemAnimLayers AnimLayers;

void SelectAnimLayer(Context context){
if(contex.use_pitsol){
Config config("Path/to/pitsol_config");
AnimLayers = ALI_ItemAnimLayers(config);
}else if(contex.use_rifle){
Config config("Path/to/rifle_config");
AnimLayers = ALI_ItemAnimLayers(config);
}
}

Pose AnimGraph(){
SelectAnimLayer(GetOwner.context);
auto Pose1 = ...;
auto Pose2 = ALI_ItemAnimLayers[FullBodyIdleState]();
return Blend(Pose1, Pose2, 0.5);
}
}

动画蓝图多线程更新

BlueprintThreadSafeUpdateAnimation 武器挂载 alt text alt text alt text alt text

alt text alt text

alt text alt text alt text