必一运动appUnity的动画图和人形动画初探

2023-10-26 20:56:20
浏览次数:
返回列表

  必一运动appUnity的动画图和人形动画初探感谢作者加菲教主供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。()

  作者主页:,作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!

  最近在试做一个射击游戏的人物动画Demo,尝试使用了部分Unity的人形动画(Humanoid),以及 Playable Graph + Animation Job的功能。目前和美术同事配合,在Unity 2018.3.0f2中初步实现了空手移动和持枪瞄准的功能,在此做个小结。为简单起见,不使用Root motion必一体育官方app下载,使用原地动画,并将动画部分视为表现层,可以读取逻辑层提供的数据,但是不写入这些数据。

  1. 核心类动画(AnimController)类:所有动画代码的驱动者。根据动画图资产、来构建动画图,并驱动动画逻辑。将数据提供者、Transform绑定等传入动画图实例。

  动画数据提供者(IAnimDataProvider)接口:动画控制代码通过这个接口,以key-value的形式来读取业务逻辑设置的数据。具体的数据类可以实现这个接口,并将其交给AnimController来使用。

  动画图资产(AnimGraphAsset)基类:从动画图中的节点抽象而成的可配置的模块,运行时可以生成实例。这个做法来自(1)。

  动画图实例(IAnimGraphInstance)接口:动画图资产的实例,最终由这些实例在运行时操作动画图。

  2. 逻辑数据的获取如下IAnimDataProvider接口用来将数据传递给控制动画的代码。

  使用这个接口就可以通过给定的关键字(key)去获取相应的数据,以及获取给定的一个状态机的当前状态。具体的数据类可以实现这个接口,每一帧由业务逻辑填充好数据。

  为什么每个函数有两个重载版本呢?这是仿照Animator和Material中查找属性的思路,如果具体数据提供者类是以散列表(如 Dictionary)实现,其关键字可用int而非String,使用的时候可以将 key 用 Animator.StringToHash 转换为int缓存起来,以提高性能。毕竟求string的散列值比较费时。

  3. 动画图资产和动画图实例这部分内容可以参考 (1)中的代码。动画图资产(AnimGraphAsset)基类继承自 ScriptableObject,用于对动画进行配置,如下:

  举例来说,角色四方向的移动需要一个混合节点,站立和四方向移动的混合又是根据 IAnimDataProvider 中读到的某个状态确定的。因此可以考虑一下几种 AnimGraphAsset:

  5. 动画图资产、实例和Playable的关系设有 A, B, C 三种动画图资产类,其.asset文件有如下依赖关系(这种依赖关系体现在编辑器拖拽的序列化字段上,箭头方向表示持有/依赖)。

  这里,箭头表示的就是获取输入的来源。即D的输入是B,C的输出,B,C的输入分别是两个A实例的输出。由于每个IAnimGraphInstance表示的是PlayableGraph的一部分,一般都会有一个Playable作为根节点(用于输出到下一级),除此可能有若干其他Playable以代码指定的方式连接起来。最终的 PlayableGraph大致是下面这个样子。

  在角色空手的站立和四向跑融合得到结果(记为 x)之后,希望根据它所持武器,将相应的上半身动画和 x 融合。设该模块的 IAnimationGraphInstance 子类中,最终输出的Playable为out(这里使用一个AnimationLayerMixerPlayable以便使用AvatarMask)。将x的输出Playable连接out的输入端口0,将第k种武器(k=1)的持枪动画(或者持枪动画和射击动画的选择结果)的Playable输出连接 out的输入端口k。对于k0的情况,设置层(也就是输入端口k的AvatarMask)即可。

  按人形做Rigging会有一个Optimize Game Objects选项,勾选后可以不暴露任何子节点或者只暴露需要的子节点。但是在这种情况下,Animator无法将这些子节点绑定成TransformStreamHandle,因此在动画图更新过程中手动调整骨骼位置和旋转(如上面调整肩膀的旋转以将武器瞄准到正确方向的功能)就无法实现。因此,目前没有打开这个选项。

  需要点击Configure... 按钮进入Avatar配置场景后,除了要检查骨骼层级结构是否映射正确,还要确定模型处于T-pose。如果模型不在T-pose上,则需要在骨骼映射下方的Pose下拉菜单中选取Enforce T-pose项强制为T-pose。不这样做会导致动画播放不正常。

  为了使得根节点没有动画曲线,除了需要在Animator上去掉Apply Root Motion选项,对于使用了 Humanoid导入的动画,还需要在FBX文件Inspector中,选中动画选项卡,做如下设置:

  如果只是在Animator上去掉了Apply Root Motion,而没有做上述设置,Unity仍然在计算时将一部分曲线算在根节点上,只是没有应用到渲染结果上,于是动画看起来会是很怪异的。

  3. Animation Job的可用性实际上这是产品化问题。我们不知道Unity什么时候会将Animation Job正式推出,目前它毕竟是试验性代码,在名字空间UnityEngine.Experimental.Animation中。另外就是,在这个部分作为正式 API 之前,有没有一种替代方式,能结合PlayableGraph 实现上面提到的这些功能?

  也欢迎大家来积极参与U Sparkle开发者计划,简称“US”,代表你和我,代表UWA和开发者在一起!

搜索