使用Unity动作融合概述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jxw167/article/details/80256633

    对于射击游戏来说,玩家需要多种动作,调动作对于美术来说工作量很大的,给读者简单的列举一下,以角色使用的手枪和冲锋枪为例,当然还有很多武器这里就不一一列举了,角色动作如下所示:


上图还不是全部完整的动作,这些动作如果我们不做融合,每个动作都需要整一个动画,这个对于动作美术简直就是一个灾难。我们作为程序在选择使用什么方式实现动画时,就要考虑这个问题了。一方面让程序自己省力,另一方面也要让美术省力;做到两全其美。

常用的动画实现方式有两种:老动画和新动画状态机,为了方便,我们肯定会选择新动画状态机,因为动画实在太多了,而且各个动作之间会有转换,老动画实现起来非常不方便,只能舍弃掉。

在动作选项里面有如下四个选项:


    以上只是一个角色的动作,游戏中会有多个角色,如果按照每个角色制作一套骨骼动画,估计美术会疯掉。所以我们采用的是Humanoid这种格式处理,当然Max导出FBX文件时需要做一些设置,这里有Max中适配Humanoid的解决方案参考网址:

http://blog.csdn.net/linjf520/article/details/79240924

这样我们只需要针对一个角色制作一套骨骼动画,其他角色跟他共用就可以了,共用骨骼动画的设置如下所示:


Source就是按照该模型制作的动画,根据上图设置一下就可以了,这样其他角色就可以使用Source对应的骨骼动画了。

前期的工作已经熟悉了,接下来介绍最重要的动作融合,我们先分析一下动作,以持枪待机为例:

站立持枪,蹲下持枪,二者最明显的区别是下半身的姿势不一样,上半身都是一样的,这对美术也是有要求的,在制作站立持枪动作时,要考虑蹲下时的状态,这样我们制作动作只需要一个站立持枪(冲锋枪)为例,蹲下持枪我们去做融合,需要做一个蹲下待机动作这样它与站立持枪进行融合,上半身不变,下半身采用蹲下的动作,如何做融合呢?Unity为我们提供好了,先看新动画状态机为我们提供的Blend Type,如下所示:


Blend Type类型分为四种,这里只有两个动作就使用了1D的混合也就是线性混合。再看持枪待机动作状态机的设置如下图所示:


这里面使用了Parameter: UpperBody_ID 以及Thresh对应的数值,这个是帮助程序执行相应的动作,对应的代码如下所示:

animator.SetFloat("UpperBody_ID", shooterManager.GetUpperBodyID(), .2f, Time.deltaTime);

这样就可以通过UpperBody_ID参数操作具体的动作了,实现的效果如下所示:

       

完成了融合动作,射击动作也是一样的,站立射击与蹲下动作,融合完成蹲下射击;站立移动射击与蹲移动,融合完成蹲行走射击等等。动作融合并不是改变现有的动作,基本动作还是不变的,我们只是将二者根据某个系数完成,不能改变动作的表现。

再看看Blend Type另一种常用类型的融合,2D笛卡尔积,采用的是二维参数如下所示:


这里面可以使用动作镜像,采用的是二维笛卡尔积融合算法。

另外,我们也可以建立多个Layers,如下图所示:


这么多层如何在代码中实现某个Layer的动画状态机,可以通过如下语句获取某个Layer:

        int baseLayer { get { return animator.GetLayerIndex("Base Layer"); } }
        int underBodyLayer { get { return animator.GetLayerIndex("UnderBody"); } }
        int rightArmLayer { get { return animator.GetLayerIndex("RightArm"); } } 
        int leftArmLayer { get { return animator.GetLayerIndex("LeftArm"); } }
        int upperBodyLayer { get { return animator.GetLayerIndex("UpperBody"); } }
        int fullbodyLayer { get { return animator.GetLayerIndex("FullBody"); } }

并且可以实现Layer的继承关系,层与层的继承关系如下图所示:


OnlyArms继承Base Layer,优先选择OnlyArms层可以使用下面语句:

animator.SetLayerWeight(onlyArmsLayer, 1.0f);

通过设置权值Weight就可以实现优先选择那个层执行,如果不优先执行就设置为0.0。


总结:

   以上是告诉读者动作混合的操作方式,主要是通过Blend Type去做动作融合,通过Parameter和Threshold的值进行不同动作的融合操作,接口代码如下所示:

    public void PlayMoveSetID(int id)
    {
        if (_animator)
            _animator.SetFloat("MoveSet_ID", id, .2f, Time.deltaTime);
    }

    //设置UpperBodyID
    public void PlayeUpperBodyID(int id)
    {
        if (_animator)
            _animator.SetFloat("UpperBody_ID", id, .2f, Time.deltaTime);
    }

我们可以在多处将Parameter设置成UpperBody_ID,这样控制一个就可以执行多个,完成动作融合。

具体逻辑如下所示:

                _roleanimator.PlayInPutVertical(1.0f);
                _roleanimator.PlayMoveSetID(1);
                _roleanimator.PlayeUpperBodyID(_shootmanager.GetUpperBodyID());

阅读更多

扫码向博主提问

海洋_

博客专家

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • 3D引擎架构
  • 服务器架构
  • GPU渲染
  • 客户端架构
  • 引擎优化
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页