TPS射击游戏实战开发(二)

Mecanim动画系统介绍


welcome

前言

为了让游戏更加真实,有时需要角色拥有丰富的角色动作,U3D的动画系统可以让我们方便进行动画的播放和管理

Animator

U3D 5 新加入的动画组件

属性


01
  1. Controller: 自己定义的 Animator Controller组件,用来控制动画的播放的主要功能组件
  2. Avatar: 人物模型
  3. Apply Root Motion: 在Unity3D动画中,模型的位置、角度经常会发生变化,我们需要决定是否将模型在动画中发生的这些变换化用到实际模型(GameObject)中。我们将这个选项的√去除,防止动画产生位置影响
  4. Update Mode:更新模式:Normal表示使用Update进行更新,Animate Physics表示使用FixUpdate进行更新(一般用在和物体有交互的情况下),Unscale Time表示无视timeScale进行更新(一般用在UI动画中)。
  5. Culling Mode:剔除模式:Always Animate表示即使摄像机看不见也要进行动画播放的更新,Cull Update Transform表示摄像机看不见时停止动画播放但是位置会继续更新,Cull Completely表示摄像机看不见时停止动画的所有更新。

使用动画系统

导入人物模型

这里提供我使用的资源包

直接将 你的人物.fbx 文件拖入Project面板


02

点击导入的模型,将模型设置为人形


03

将人物模型拖入Hierarchy面板

为模型对象添加 Animator

  1. 在project 空白区域右击 Creat -> Animator Controller
  2. 为创建的人物object添加组件 Animator 并绑定上一步创建的控制器
  3. 双击控制器

状态机


04

概念

  • 状态机是用来管理动画的基本单位
  • 一个初始的控制器有着以上三个基本状态 Entry: 初始状态 Any State: 任何状态 Exit: 退出

创建第一个动画

  1. 右击空白处 Creat State -> Empty 创建一个新的状态机
  2. 这是我们会看到 从 Entry有一条线连接到了新创建的状态机上,这意味着控制器一进入就会播放 这个状态机的动画
  3. 导入动画文件,与人物的导入方法一样,直接拖入Project ,新建一个Animations 文件夹专门用来存放 动画文件
  4. 双击新状态机 在检视面板可以看到 Motion一项为 None,拖入或者点击右边的圆点来导入一个动画文件

同样动画文件也需要设置为人形,并且设置为循环播放,将动画的模型更改为你的模型(在Animations文件夹中 Ctrl + A全选所有文件可以批量更改,如果不更改模型,U3D会自动用一个自带模型的骨骼来播放动画,就会显得不协调)


05

运行一下试试看


06

这鬼畜的动作(-。-)

Blend Tree 混合树动画系统

可以用参数来控制动画的播放,优点是可以平滑的切换动画

具体操作

  1. 右键 Creat State -> From New Blend Tree 创建一个混合动画树
  2. 双击动画树,点击中间的根节点,把右侧的检视面板中的 Blend Type 设置为 2D simple Directional

接下来用操作演示 如何创建变量


07

在右侧的设置面板中用刚刚创建的两个变量设置坐标


08

点击右下角的 加号 ->Add Motion Field 添加新的动画区,并绑定动画,设置相应的坐标

我设置的9个动画状态


09

来看看如何用代码控制动画的播放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using UnityEngine;
public class SwatC : MonoBehaviour {
private Animator anim;
//存储变化的插值
private float Lerp_x;
private float Lerp_y;
private bool isAction;
public GameObject speed;
void Start () {
//获取动画控制组件
anim = GetComponent<Animator>();
isAction = false;
}
void FixedUpdate () {
if (Input.GetMouseButton(0))
{
if (!anim.GetBool("Shift"))
{
anim.SetBool("Fire", true);
}
else
{
anim.SetBool("Shift", false);
speed.SendMessage("setSpeed", 5f);
}
}
else
{
anim.SetBool("Fire", false);
isAction = true;
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
if (!anim.GetBool("Shift"))
{
anim.SetBool("Shift", true);
anim.SetBool("Ctrl", false);
speed.SendMessage("setSpeed",10f);
}
else
{
anim.SetBool("Shift", false);
speed.SendMessage("setSpeed", 5f);
}
}
if (Input.GetKeyDown(KeyCode.LeftControl))
{
if (!anim.GetBool("Ctrl"))
{
anim.SetBool("Ctrl", true);
anim.SetBool("Shift", false);
speed.SendMessage("setSpeed", 2f);
}
else
{
anim.SetBool("Ctrl", false);
speed.SendMessage("setSpeed", 5f);
}
}
if (Input.GetKey(KeyCode.W))
{
Lerp(0, 1);
isAction = true;
}
if (Input.GetKey(KeyCode.A))
{
Lerp(-1, 0);
isAction = true;
}
if (Input.GetKey(KeyCode.W)&& Input.GetKey(KeyCode.A))
{
Lerp(-1, 1);
isAction = true;
}
if (Input.GetKey(KeyCode.S))
{
Lerp(0, -1);
isAction = true;
}
if (Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A))
{
Lerp(-1, -1);
isAction = true;
}
if (Input.GetKey(KeyCode.D))
{
Lerp(1, 0);
isAction = true;
}
if (Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.D))
{
Lerp(1, -1);
isAction = true;
}
if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D))
{
Lerp(1, 1);
isAction = true;
}
if (!Input.anyKey)
{
isAction = false;
Lerp(0, 0);
SetBlendTree();
}
if (isAction)
{
SetBlendTree();
}
}
//动画渐变插值计算
void Lerp(float target_x,float target_y)
{
Lerp_x = Mathf.Lerp(Lerp_x,target_x,0.15f);
Lerp_y = Mathf.Lerp(Lerp_y, target_y,0.15f);
}
//设置混合动画
void SetBlendTree()
{
anim.SetFloat("X", Lerp_x);
anim.SetFloat("Y", Lerp_y);
}
}

主要方法

1
2
3
4
5
6
7
8
Animator anim;
//获取动画组件
anim=getCompent<Animator>();
//使用 set方法控制 自己定义的变量的值
anim.setBool("你定义的变量的名称",true/false)
anim.setFloat("你定义的变量的名称",value)
通过控制变量的变化来切换动画
还有其他几种方法 大家可以自己试试

将这个脚本绑定在人物模型上就可以控制角色前后左右移动以及奔跑下蹲了
插值计算主要是用来进行动画的过渡平滑

我的三个混合树,(混合树之间的连线,可以右击树 Make Transition 并定义新的变量实现树之间的转换)


10

结语

下一篇文章介绍人物控制器和鼠标控制镜头移动

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 前言
  2. 2. Animator
    1. 2.1. 属性
  3. 3. 使用动画系统
    1. 3.1. 导入人物模型
    2. 3.2. 将人物模型拖入Hierarchy面板
    3. 3.3. 为模型对象添加 Animator
    4. 3.4. 状态机
      1. 3.4.1. 概念
      2. 3.4.2. 创建第一个动画
    5. 3.5. Blend Tree 混合树动画系统
    6. 3.6. 具体操作
  4. 4. 结语