Unity3D教程:动画系统教程

转自 : 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(); 
 
}


    在动画播放方式上,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); 
 
  
}


要让我们控制的机器人可以一边跑一边射击,那么就必须要用到 unity 中一个非常重要的动画技术 “动画混合Animation Mixing”。
找个动画文件来看看: [email protected] 这个动画。在这套动画文件中,包含了很多的动画动作。我们的每一个动画都包含了好多的动作,其中包括了 手上的动作和腿脚的动作。通常情况下我们播放动画就是直接播放一个动作就可以了,但是遇到需要动作融合的时候,就不能直接的调用动画,而是要选用其中的一部分有用的动画。 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)