# 动画状态机

# 一、模型和动画

# 1.1 模型和动画素材获取

美术老师会用3DS Max或者MaYa软件制作三维模型,并给模型绑定制作相应的动画。每个模型中是可以包含多个动画的,比如走、跑、跳、蹲、攻击、防御,如果是包含了多个动画,那么在模型的导入设置中,就需要对这些动画进行切分。

动画也可以和模型进行分开,Unity的Avatar系统就是一种让模型和动画分离的技术。简单来说,就是模型的骨骼和动画的骨骼匹配,然后动画的骨骼就可以想阿凡达那样驱动模型进行骨骼动画的播放。

为了节省时间和金钱,建议使用一些免费的带动画的模型进行学习。下面推荐一个不错的网站:

https://www.mixamo.com/

这个网站有免费的模型和动画可以供你学习使用。进入网站后,首先选择你喜欢的角色,我们选择Remy。

image-20230702213259065

然后再在Animations页面进行动画的预览和选择。在搜索框中输入pack并按enter,可以过滤出一些动画包。然后我们选择Basic localmotion,预览。

image-20230702214026821

然后点击右侧黄色的下载按钮,填写下载选项,即可下载该带动画的模型,非常方便。

image-20230702214801518

下载的文件解压后文件列表如下:

image-20230702215403011

其中Remy.fbx是模型文件,其它的则是对应的动画文件。

# 1.2 模型的导入设置

上面解压后的模型文件,拖放到项目中指定的文件夹下面,并选中Remy.fbx,在它右侧的Inspector面板中修改它的导入设置,修改后,点击面板上的Apply应用设置。

图1:

image-20230702220541389

图2:

image-20230702220951509

图3:

  • Model:模型设置保持默认
  • Rig:骨骼设置如图1,Animation Type选择Generic,Avatar Definition选择Create From This Model,其它保持默认
  • Animation:如图2,Animation设置为不导入,因为我们要用其它文件中的动画
  • Materials:模型的设置如下,修改后点击Apply

# 1.3 动画的导入设置

选中idle.fbx,在检视面板中修改它的属性,

Model:设置保持默认

Rig:设置中,配置为如下所示:

image-20230702223145396

Avatar Definition选择Copy From Other Avatar,Source选择模型上挂在的Avatar。然后点击Apply应用。

Animation:设置,保持默认。

Materials:选择None,无材质球生成

然后每个动画文件都设置为一样。

# 1.4 模型摆放

把Remy.fbx拖放到场景中,并调整摄像机位置到一个合适位置。

image-20230702223921864

# 二、动画状态机配置

# 2.1 新建并绑定AnimatorController

在Project面板中,Assets文件夹下面右键新建一个 Animator Controller文件,并重命名为RemyAnimator。然后在场景中,选中Remy,可以看到Remy上有一个Animator组件,上面的Controller槽位是空的,我们从Project下面选中RemyAnimator并把它拖放到Controller槽位中,即完成了AnimatorController的绑定。

image-20230703145901943

# 2.2 给AnimatorController添加动画

双击RemyAnimator.controller,即可打开Animator面板。里面显示了当前RemyAnimator动画状态机。

在Project面板中打开我们的模型文件夹,把idle的动画节点拖放到状态机中,这样就给状态机增加了一个节点。在状态机中选中这个节点,就可以对这个节点的属性进行编辑。

image-20230703150806876

比如修改这个节点的名称,它关联的动画的播放速度,播放时长,播放偏移,足部IK,以及切换条件等。可以看到当我们第一个Idle动画置入状态机后,里面产生的这个节点颜色是橘黄色的,它代表着它是默认节点。当我们运行程序时候,Remy这个角色就默认播放这个动画。如下图所示:

image-20230703151623594

# 2.3 状态切换

刚刚我们实现了一个默认动画的播放,是角色空闲状态动画。大部分时候我们需要做一个动画切换,比如从idle切换到走路。我们把walk动画拖放到状态机中,然后再idle节点上,右键>>make transition来连接walk节点。就建立好了一个动画状态机的的切换。同样的操作,建立一条从walk到idle的连线。

但是这个切换是默认idle动画播放完一轮后就直接切换到walk,这样是不对的,我们想要的是当我们点击了w之后,玩家才开始walk。那么就需要增加切换条件。即给状态机添加参数。

如下图所示,在动画状态机的Parameters Tab页下面,点击‘+’来添加一个Bool类型变量,名为isWalking。通过这个变量来进行动画切换。

image-20230703152352638

然后选中idle到walk的这条连线,并给它添加切换条件,isWalking:true。这个isWalking就是在状态机的参数列表中我们添加的isWalking参数。

image-20230703153541660

同样的方法,在walk到idle的连线上设置切换条件为isWalking:false。

# 2.4 代码设置动画切换参数

我们新建一个脚本AnimCtrl.cs,并添加如下代码:

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

public class AnimCtrl : MonoBehaviour
{
    Animator myAnimator;
    // Start is called before the first frame update
    void Start()
    {
        myAnimator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.W)) {
            myAnimator.SetBool("isWalking", true);
        } else {
            myAnimator.SetBool("isWalking", false);
        }
    }
}

这个脚本实现了当按下W按键时候,角色就播放Walk动画,松开就播放Idle动画。

这个脚本需要绑定到场景中Remy模型上面使用,运行效果如下:

image-20230702223921864