第三十四章 Unity人形动画(上)

在我们DirectX课程中,我们讲过一个模型最少拥有网格和材质,可以没有动画。游戏场景中的静态物体就可以是这样的模型,例如花草树木,建筑物等等,他们通过MeshRenderer就可以渲染。对于一个带有动画的FBX文件,里面不仅仅包含了网格和材质,还包括了“骨架”和动画数据,这里的动画数据其实就是骨架中每块骨骼的移动和旋转变换数据。这里大家一定要分清骨架和骨骼两个概念哦。这样的模型需要使用SkinMeshRenderer才可以渲染。我们知道,骨骼动画就是骨骼变换控制网格顶点变换形成的,两者是通过“蒙皮”产生的关联关系,“蒙皮”的过程就是骨骼对顶点影响的权重设置。这里面涉及到了两种数据,一种是网格和材质,另一种就是骨骼动画。前者是差异化的,每个模型肯定都是不一样的;而后者有可能共享通用的,每个模型可能会有相同的动画。例如,两个人物模型,他们都应该有待机,走路,跑步等等通用的动画。那么,这些动画数据能不能独立成单独的文件,被其他模型使用呢?如果可以使用的话,我们就不需要为每一个模型制作动画了,节省一些不必要的时间了。答案,肯定是可以的。从数据角度出发,两个不同的模型,只要他们的“骨骼结构”(骨架)是一样的,那么基于该骨架的动画数据,就可以重用。这里的一样指的是骨骼的数量以及父子关系大致保持一致,名称不一样可以通过“映射”来统一。在3ds max中,就提供了一个完整的人形骨架,称之为“Biped”,如下所示:

也就是说,如果大家在给人物模型添加骨架的时候,都使用“Biped”的话,那么我们所有的基于“Biped”的动画就可以重用了。事实上,3ds max也是这样设计的,我们可以从网上下载到很多的基于“Biped”的动画数据。在Unity中,同样也拥有一套人形骨架,如下:

Unity的人形骨架与3ds max的人形骨骼大致相同。但是,大部分情况下,我们还需要将两者的骨骼进行一个“映射”,也就是“mapping”。映射的目的就是为了让Unity能够知道模型上面的那些骨骼对应Unity自己的头部,身体,胳膊以及腿脚信息等等。这个应该很容易理解。

Mecanim Example Scenes是由Unity发布的一款免费资源,旨在指导开发者如何使用Unity的Mecanim及角色动画系统,项目中包含11个示例场景,分别演示了动画状态机、混合树、集群模拟、多层次IK、目标匹配、处理武器、跟随、预测及导航网格集成等。

我们在Assets资源面板中导入上面的资源包。如下所示:

 

这个资源包并没有统一放置到一个独立的文件夹中,比较乱。我们发现在Assets根目录下有很多的场景文件,我们随便打开一个“Animator Controller.unity”查看一下。

当我们Play运行之后,就可以通过WASD键来控制里面的人物模型移动了,同时会有移动动画。当然,这个不是我们研究的内容。这个人物模型存放在 “Assets\Characters\U_Character”目录下,如下所示

在这个目录下,我们可以看到材质,贴图以及模型 “U_Character_REF.fbx”文件,查看它的Inspector检视视图。

我们注意到它的Animation Type一项为 Humanoid类型,也就是人形动画。关于这一项,我们之前已经介绍过Legacy旧版动画 和Generic新版动画,而Humanoid就是新版人形动画。我们继续点击“Animcation”选项面板,查看其下动画剪辑内容。

我们发现,这个模型文件并没有动画剪辑数据。我们重新创建一个新的“SampleScene3.unity”场景,然后将这个模型文件拖拽到Scene视图中,如下所示

我们在“Hierarchy”层次面板中查看该文件中有什么数据信息吧。

其中顶级“U_Character_REF”是我们整个游戏对象,它的下面有U,U_Char,U_Char_Eye_L,U_Char_Eye_R四个子对象,后面三个分别是人物主模型,人物左眼模型和人物右眼模型。那么第一个U对象是什么呢?U是一个父对象,它的下面有一个“joint_Char”的对象,这个对象就是“人形骨架”的根骨骼。我们上面已经说明过,动画数据是可以共享的,模型想要从外部获取动画的话,它本身必须拥有“人形骨架”,并且是被“蒙皮”处理过的。应该蒙皮处理过的模型需要“Skinned Mesh Renderer”组件才能渲染出来。我们点击U_Char查看Inspector检视视图,就能看到这个渲染组件,如下

在上面的“Root Bone”一项中,就能看到根骨骼就是“joint_Char”了。我们上面也提到了,这个模型是没有动画剪辑的(但是有骨骼信息),那么动画信息在哪里呢?

接下来,我们去“Assets\Animations”目录下查看一下,

我们会发现,有很多的动画片段,例如Idles,Run,Jump等等。这些专门的动作文件是怎么来的呢?他们也是可以通过3ds max导出来的,操作很简单,我们只需要在3ds max中选中“骨架”,然后导出FBX文件,再导出设置中只勾选“Animation”动画一项。我们还可以设置开始帧数和结束帧数。Untiy要求导出的文件名称格式为“模型名@动画名”。例如,我们可以给之前的“Elf”单独导出一个攻击的动画文件“Elf@Attact.FBX”,如下所示

导出“Elf@Attact.FBX”之后,我们将其复制到“Assets/Elf2”目录下查看

我们可以点击这个动画,在Inspector中的Animation选项卡中查看这个动画效果。

有兴趣的同学,可以将这个动画片段添加到“动画控制器”中进行编辑。接下来,我们继续查看“U_Character_REF”模型对应的动画,例如“Run”动画,效果如下

接下来,我们就使用Idles,Run,Jump这三个动画来演示一下吧。首先,我们在“Hierarchy”层次视图中选中“U_Character_REF”这个游戏对象,查看它的Inspector检视视图。如果没有“Animator”组件的话,我们就给它添加一个,如下所示

毫无疑问,我们需要先创建一个动画控制器。在Asset视图空白处,右击选择“Create”-》“Animator Controller”,将其命名为“U_Character_Animator_Controller”

接下来,我们双击这个文件,打开“Animator”窗口,如下

然后,我们将上面提到的Idles,Run,Jump三个动画文件拖拽进来。

默认是Idle动画,这个问题不大。接下来,我们需要链接Idle到Run动画。我们在“Idle”动画状态上面右击选择“Make Transition”,然后移动鼠标到“Run”动画状态上面点击完成。然后我们继续链接“Run”到“Jump”,如下所示

接下来,我们在创建一个“动画参数”,这次我们创建一个Int类型的“run_jump”变量

接下来,我们点击“Idle”到“Run”之间的连线,并在Inspector检视视图中编辑

这次我们选择的操作符是“Equals”等于操作符,对应的数值是1

然后我们点击“Run”到“Jump”之间的连线,设置操作数值为 2

这样的话,当我们设置“run_jump”为数值1的时候,我们的游戏角色就会从idle状态过渡到run状态,然后设置为数值2的时候,就会从run状态过渡到Jump状态。这个动画控制器设置完毕后,不要忘了将它拖拽到“Animator”组件的“Controller”栏中去。

在上图中,我们还有一个小问题要调整。就是取消“Apply Root Motion”勾选项。它的意思是说,当我们播放动画的时候,人物模型不会产生移动,也就是原地播放动画。接下来,我们来创建一个C#脚本,命名为“U_Character_Animator_Script.cs”,内容如下所示

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class U_Character_Animator_Script : MonoBehaviour
{
    // 动画播放组件
    private Animator animator;

    // Start is called before the first frame update
    void Start()
    {
        // 获取Animator组件
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            animator.SetInteger("run_jump", 1);
        }
        if (Input.GetKeyDown(KeyCode.J))
        {
            animator.SetInteger("run_jump", 2);
        }
    }
}

以上的代码非常简单,我们就不再过多的解释了。我们将脚本附加到人物角色上后运行工程。

运行工程之后,我们就发现了几个问题。首先,工程运行后自动播放idle动画,这个没有问题。但是,必须等idle动画播放完毕后,我们才能按下W键进入跑步动画,紧接着我们继续按下J键播放jump动作。如果不想等待idle动画播放完毕就能直接进入跑步动画的,可以点击“idle”到“run”之间的过渡线,然后取消掉“Has Exit Time”选项,如下所示

最后,人物模型就静止不动了。因为jump动画不是循环播放,且此时run_jump的数值等于2。如果想让人物模型继续进入idle动画或者run动画的话,我们需要重新设置run_jump的数值了。因此,这里的动画切换逻辑需要重新设计一下。例如,当我们按下W键的时候,设置run_jump数值为1,当按起的时候,设置run_jump数值为2。这里我们就不再演示了。

本课程涉及的内容已经共享到百度网盘:https://pan.baidu.com/s/1e1jClK3MnN66GlxBmqoJWA?pwd=b2id

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咆哮的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值