转自 : 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);
}
}
|
Unity3D动画系统实战
本文详细介绍Unity3D动画系统的使用方法,包括动画融合、混合、叠加等高级特性。通过实例演示如何控制动画播放,实现角色行走、射击等复杂动画效果。
2131

被折叠的 条评论
为什么被折叠?



