转自 : http://www.unitymanual.com/thread-1906-1-1.html
动画系统非常的灵活强大,动画系统支持动画融合、混合、叠加动画,行走循环的时间同步,动画层,控制动画的各个方面,以及支持基于物理的布娃娃系统和程序动画。这里做个笔记文章,记录整个从0开始使用Unity的动画系统。下载官网的CharacterAnimation例子里面带有3个动画模型,以及这三个模型的简单调用的例题。unity3d教程手册
Unity3D教程:动画系统教程(一)
这里例题中包含三个基本的数据模型,Goober是一个简单的小丑,Robot则是一个机器人战士,Soldier是一个人类战士。

Unity3D教程:动画系统教程(一)
在自带的动画模型里,除了模型Robot以外,还包含了很多@XXX结尾的动作,我们调用的时候,只需要按照@后面的动作名称调用即可。
1)新建一个场景,创景地形,并且将Robot模型拖到场景中。

Unity3D教程:动画系统教程(一)
这个时候的场景中是没有任何代码的,直接运行场景,你就能看到这个模型在运行“idle”动作。

Unity3D教程:动画系统教程(一)
看来Unity不但自己加载了模型,而且识别出了动作,自动调用了待机动作。为了防止Unity自己的动作影响到我们的代码操作,在开始的时候我们就把默认动作关闭。创建一个JS脚本,加入如下代码:
[C#]
纯文本查看
复制代码
1
2
3
4
5
6
7
|
function Start ()
{
animation.Stop();
}<!--DVFMTSC-->
|
在动画播放方式上,Unity有两种方法,一种是Play(),这种方式的动画没有任何混合,直接播放动作,这样的动作看起来比较生硬,而且在Unit用的官方文档里建议个别动画可以使用Play()方式播放,那似乎是不建议使用Play来播放动画;另外一种是Animation.CrossFade。这是一种再带混合的动画播放模式,他可以让动画逐渐变化,而不是生硬的切换。Unity3D教程手册
这就是动画融合的用武之地。在Unity同一个角色可以拥有任意数量的动画。所有动画被融合或添加在一起,来产生最终
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
// Makes a character contains a Run and Idle animation
// fade between them when the player wants to move
// 让一个角色包含Run和Idle动画,并且在玩家想移动的时候在他们之间淡入淡出。
function Update () {
if
(Mathf.Abs(Input.GetAxis(
"Vertical"
)) > 0.1)
animation.CrossFade(
"Run"
);
else
animation.CrossFade(
"Idle"
);
}
|
将上面这段代码拷贝到JS脚本中,我们按方向键就可以看到刚刚的Robot在“Run”和“Idle”两个动画柔和切换的动作变化。
如今的游戏,Animation Blending是确保角色平滑动画的一项重要功能。动画师创建的分段动画,如:行走循环、跑步循环、 空闲动画或射击动画。在游戏的任何时间点都有可能从空闲转换到走动,反之亦然。当然你不希望两个不同的动作之间突然跳转,想要动画平滑过渡。
通过animation还可以设定动画的运行方式,可以animation.WrapMode方式来修改是否循环播放。
[C#]
纯文本查看
复制代码
1
2
3
|
animation.wrapMode = WrapMode.Loop;
animation[
"jump"
].wrapMode = WrapMode.Clamp;
|
动画层可以控制玩家的动画播放优先级,具体的用法似乎还挺丰富的,从文档上看,最起码的用途是可以在其他的动画还在播放的时候,优先播放而不影响底层级的动画。比如当层级都是1,在跑动的时候,点击射击按钮,则没有反应会一直奔跑。如果设定射击的动作层级为1,其他都为0的时候,跑动的时候点射击,角色就会执行射击动作。
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
function Start ()
{
// Set all animations to loop
animation.wrapMode = WrapMode.Loop;
// except shooting
animation[
"shoot"
].wrapMode = WrapMode.Once;
// Put idle and walk into lower layers (The default layer is always 0)
// This will do two things
// - Since shoot and idle/walk are in different layers they will not affect
// each other's playback when calling CrossFade.
// - Since shoot is in a higher layer, the animation will replace idle/walk
// animations when faded in.
animation[
"shoot"
].layer = 1;
// Stop animations that are already playing
//(In case user forgot to disable play automatically)
animation.Stop();
}
|
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
function Update () {
if
(Mathf.Abs(Input.GetAxis(
"Vertical"
)) > 0.1 || Mathf.Abs(Input.GetAxis(
"Horizontal"
)) > 0.1)
animation.CrossFade(
"run"
);
else
animation.CrossFade(
"idle"
);
// Shoot
if
(Input.GetButtonDown (
"Fire1"
))
animation.CrossFade(
"shoot"
);
}
|
测试一下控制角色,这样在上次人物动作的基础上让角色可以在场景里面跑起来。首先为角色增加一个CharacterController。然后设定一些变量控制角色的速度。
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
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
|
var speed = 3.0;
var rotatationSpeed = 200.0;
private
var curSpeed = 0.0;
function Update () {
// Rotate around y-axis
var newRotation = Input.GetAxis(
"Horizontal"
) * rotatationSpeed;
transform.Rotate(0, newRotation * Time.deltaTime, 0);
// Calculate speed
var newSpeed = Input.GetAxis(
"Vertical"
) * speed;
if
(Input.GetKey(
"left shift"
))
newSpeed *= 1.5;
// Move the controller
var controller : CharacterController = GetComponent (CharacterController);
var forward = transform.TransformDirection(Vector3.forward);
controller.SimpleMove(forward * newSpeed);
}<!--DVFMTSC-->
|
要让我们控制的机器人可以一边跑一边射击,那么就必须要用到 unity 中一个非常重要的动画技术 “动画混合Animation Mixing”。
找个动画文件来看看: robot@idle2shoot.fbx 这个动画。在这套动画文件中,包含了很多的动画动作。我们的每一个动画都包含了好多的动作,其中包括了 手上的动作和腿脚的动作。通常情况下我们播放动画就是直接播放一个动作就可以了,但是遇到需要动作融合的时候,就不能直接的调用动画,而是要选用其中的一部分有用的动画。 unity3d 教程手册

现在我们要对Run这个动作和Shoot两个动作进行混合。先来看看Shoot的动作序列:在这个动作中基本上只包含了两个上身持枪和动作,下身基本上没动。这个动作融合主要是针对shoot的上半身。

首先,利用Shoot动画片段,生成一个新的动画片段“shootUpperBody”
[C#]
纯文本查看
复制代码
1
2
3
4
5
6
7
|
animation.AddClip(animation[“shoot”].clip, “shootUpperBody”);
animation[“shootUpperBody”].AddMixingTransform(transform.Find(“mover/roothandle/spine1”));
animation[“shootUpperBody”].AddMixingTransform(transform.Find(“mover/gun”));
|
增加两个混合矩阵,让动作融合。这个动画角色的动作骨骼矩阵包含四部分,我们选择的spine1是上身的动作矩阵的根矩阵:

然后在运动的代码中调用
[C#]
纯文本查看
复制代码
1
|
animation.CrossFadeQueued(
"shootUpperBody"
, 0.3, QueueMode.PlayNow);
|
然后跑起来的的角色,就有shoot和run混合的效果。Unity3D教程手册
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
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
|
function Update () {
if
(Mathf.Abs(Input.GetAxis(
"Vertical"
)) > 0.1 || Mathf.Abs(Input.GetAxis(
"Horizontal"
)) > 0.1)
{
animation.CrossFade(
"run"
);
animation[
"run"
].speed = Mathf.Sign(Input.GetAxis(
"Vertical"
));
}
else
animation.CrossFade(
"idle"
);
// Play the cross fade animation
if
(Input.GetButtonDown (
"Jump"
))
{
animation.CrossFade(
"jump"
, 0.3);
}
// Shoot
if
(Input.GetButtonDown (
"Fire1"
))
{
// We are running so play it only on the upper body
if
(animation[
"run"
].weight > 0.5)
animation.CrossFadeQueued(
"shootUpperBody"
, 0.3, QueueMode.PlayNow);
// We are in idle so play it on the fully body
else
animation.CrossFadeQueued(
"shoot"
, 0.3, QueueMode.PlayNow);
}
}
|