关于模块化角色的问题

我们项目现阶段计划用LeaderPose进行角色模块化后的动画驱动,但是遇到一个比较棘手的问题,就是Leader必须拥有完整的骨骼才能够驱动Follower的动作,因为我们项目是一款持续运营并有换装需求的游戏,我们并不能在初期就预设好Follower会有多少多出来的骨骼,这就导致后续可能会面临每次做一套新的服装,就会需要更新一次Leader的骨骼,而且骨骼数量会非常爆炸。

所以想要咨询下几个问题

1.使用LeaderPose来进行角色模块化的情况下,推荐用什么方式来处理这种后续会增加额外骨骼的问题。

2.CopyPose可以解决模块化各部分骨骼不相同的问题,但是根据文档的说法他的游戏线程成本比LeaderPose高很多,那这个效率的差距大概是什么程度。

您好,

1、使用LeaderPose来进行角色模块化的情况下,推荐用什么方式来处理这种后续会增加额外骨骼的问题。

  • Follower并一定需要完全匹配Leader,对于额外的骨骼和层级不同的骨骼,代码内有一套匹配机制,大致是让这些多余的骨骼保持Reference Pose的Transform。
  • Follower其实也是可以跑自己单独的动画蓝图的,可见接口USkinnedMeshComponent::SetLeaderPoseComponent中的第三个参数bInFollowerShouldTickPose(对应的蓝图节点类似),可以让差异的部分执行自己的动画逻辑。
    • 这里需要注意SkeletonMesh在更新的时候会有一些LeaderPoseComponent.isValid的检查
    • 这种做法和初衷相违背,LeaderPose方案的核心价值在于避免重复的动画计算,建议谨慎选择
  • 可以尝试将这些额外的骨骼制作成独立的部件,不设置到LeaderPoseComponent上,自己单独由物理驱动或者由动画蓝图驱动,若是动画蓝图驱动,可以有自己的CopyPose逻辑、蓝图逻辑或者ControlRig逻辑。

2.CopyPose可以解决模块化各部分骨骼不相同的问题,但是根据文档的说法他的游戏线程成本比LeaderPose高很多,那这个效率的差距大概是什么程度。

  • Leader Pose方案,各个部件不运行动画蓝图,在引擎底层直接指向Leader 的骨骼变换数组,相当于引用传递,这也是它在GameThread上消耗低的主要原因。
  • Copy Pose方案,各个部件需要运行自己的动画蓝图,即便动画蓝图支持并行计算,但依然有必要的逻辑需要在Game Thread执行。
  • 在"Copy Pose"这个过程中,它也不是简单数据拷贝,它也涉及一些需要消耗Game Thread的计算,包含骨骼映射、矩阵计算、内存分配、释放和拷贝、曲线拷贝、用户自定义数据拷贝等

感谢回答。

可能表述不清楚,目前主要是Leader里面缺少一部分Follower中用来作为飘带的骨骼。

尝试了下就算勾选​了FollowerShouldTickPose,也并没有执行ABP中的逻辑

你的飘带是用动画来驱动还是物理驱动? 你说“没有执行ABP”是指ABP没有Update吗?还是你连的ABP逻辑没有走到你理想的状态?

不知道是否方便提供一个简单的脱敏测试用例,我们帮你看一看

都有尝试过,RigidBodyNode没有效果,然后只针对飘带的一根骨骼进行ModifyBones,或者给裙摆特意K一个Sequence然后播放,都没有动画

我也测试了一下,发现之前对​bInFollowerShouldTickPose参数理解有误,这里更正一下。

Follower如果设置了LeaderPose​,同时bInFollowerShouldTickPose为True,确实会TickPose,但是这个TickPose是代码层面的。

若是你看过SkeletalMeshComponent更新相关的代码,会发现有个TickPose的函数调用,但是不会RefreshBone。简单就是说,Follower的动画蓝图会更新,但是更新的结果不会应用到角色的Pose上。

这么做的主要目的是让Follower上的动画蓝图仍能提供一些辅助作用,例如,Follower的动画蓝图在更新,它的动画事件依然会发送,用户依然可以拿这些动画事件做相关的逻辑。

总结一下,​Follower若是设置了LeaderPose,它就只能跟随它的LeaderPose,即便它身上有动画蓝图,也不能影响角色最终Pose的表现,这也是比较符合LeaderPose的设计初衷的。

针对你的需求,我们建议你尝试一下CopyPose方案,在很多项目中都有相关的使用。​