Unity3D之Legacy动画系统学习笔记

Unity3D的Mecanim动画系统是非常强大的,而且作为Unity推荐的动画系统,其未来会完全代替老的一套动画系统,即Legacy动画系统。目前的情况是Mecanim与Legacy两套动画系统同时共存,但是并不是说Legacy动画系统就没有任何价值了,作为Unity4.0以前使用的动画系统,我认为还是很有必要去了解和学习的,所以就有了这篇笔记。

Legacy动画系统

http://docs.unity3d.com/Manual/Animations.html

我们可以使用Unity自带的资源来学习老版本的动画系统,新建Unity3D项目,选择菜单“Assets”->“Import Package”->“Character Controller”,导入的资源里的那个小人就是使用Legacy动画系统的模型,我们的学习可以基于他来进行。

模型文件

在骨骼这一项中,我们发现动画类型的设置就是Legacy,说明这个模型使用的动画类型为老版本的动画系统。

我们再看看动画页:

动画页中,我们可以对动画剪辑进行编辑。

控制动画

我们直接将FBX文件拖入场景,Unity会自动帮我们添加Transform和Animation两个组件(注意Mecanim动画系统使用的是Animator组件,Legacy动画系统使用的是Animation组件)。

Animation组件的设置还是比较简单的:

  • Animation:当前播放的动画。
  • Animations:所有可以播放的动画。
  • Play Automatically:是否自动播放。
  • Animate Physics:动画是否和物理世界进行交互。
  • Culling Type:动画在不可见时是否还继续播放,优化选项默认即可。

点击播放按钮就可以看见动画正常播放了。

脚本控制

http://docs.unity3d.com/ScriptReference/Animation.html

下面我们来看看如何使用脚本控制动画的播放,我们将下面的脚本绑定到人物身上即可。

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class AnimationScript : MonoBehaviour
 5 {
 6     private Animation _animation;
 7
 8     void Start()
 9     {
10         _animation = this.animation;
11     }
12
13     void OnGUI()
14     {
15         //直接播放动画
16         if(GUI.Button(new Rect(0, 0, 100, 30), "idle"))
17         {
18             _animation.Play("idle");
19         }
20         if(GUI.Button(new Rect(100, 0, 100, 30), "walk"))
21         {
22             _animation.Play("walk");
23         }
24         if(GUI.Button(new Rect(200, 0, 100, 30), "run"))
25         {
26             _animation.Play("run");
27         }
28         if(GUI.Button(new Rect(300, 0, 100, 30), "jump_pose"))
29         {
30             _animation.Play("jump_pose");
31         }
32         //使用融合来播放动画
33         if(GUI.Button(new Rect(0, 30, 100, 30), "idle"))
34         {
35             _animation.CrossFade("idle");
36         }
37         if(GUI.Button(new Rect(100, 30, 100, 30), "walk"))
38         {
39             _animation.CrossFade("walk");
40         }
41         if(GUI.Button(new Rect(200, 30, 100, 30), "run"))
42         {
43             _animation.CrossFade("run");
44         }
45         if(GUI.Button(new Rect(300, 30, 100, 30), "jump_pose"))
46         {
47             _animation.CrossFade("jump_pose");
48         }
49     }
50 }

运行程序,会看见两排按钮,其中第一排按钮使用Play方法来切换动画,而第二排按钮则使用CrossFade来播放动画。

Play与CrossFade的区别

以从跑步切换到站立动画为例来看:

Play:直接切换动画,如果人物之前处于倾斜跑步状态,则会立即变成站立状态,表现上比较不真实,特别是当两个动画姿势差别较大时。

CrossFade:通过动画融合来切换动画,第二个参数可以指定融合的时间,如果人物之前处于倾斜跑步状态,则会在指定的融合时间内逐渐变成站立状态,表现上接近真实的人物动作切换效果。

但是当使用CrossFade播放跳跃动画时会出现问题,主要问题是跳跃动画不是循环播放且其持续时间小于动画融合的时间,我们修改为下面的脚本指定融合时间短一点就可以正常进行跳跃的融合播放了:

_animation.CrossFade("jump_pose", 0.1f);

PlayQueued

该方法可以指定当当前的动画播放完毕后接下来播放的动画,如下:

_animation.PlayQueued("run", QueueMode.CompleteOthers, PlayMode.StopSameLayer);

文件格式和资源加载

我们的模型使用通用的FBX格式,那么动画文件的储存一般有两种情况,一是所有的动画和模型都一起存放到一个文件中,还有一种情况是模型单独一个文件而动画单独一个文件。

模型动画都存放在一个文件中的情况

类似于Unity提供的Character Controller中的资源就是这样的结构,一个FBX文件保存了模型、骨骼和动画:

Resources加载

我们直接加载该资源就可以直接使用,将下面的脚本绑定到摄像机即可,脚本如下:

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class AllInOneResourcesLoad : MonoBehaviour
 5 {
 6     private Animation _animation;
 7
 8     void Start()
 9     {
10         GameObject go = Resources.Load<GameObject>("Standard Assets/Character Controllers/Sources/PrototypeCharacter/Constructor");
11
12         GameObject man = Instantiate(go) as GameObject;
13         _animation = man.animation;
14     }
15
16     void OnGUI()
17     {
18         //直接播放动画
19         if(GUI.Button(new Rect(0, 0, 100, 30), "idle"))
20         {
21             _animation.Play("idle");
22         }
23         if(GUI.Button(new Rect(100, 0, 100, 30), "walk"))
24         {
25             _animation.Play("walk");
26         }
27         if(GUI.Button(new Rect(200, 0, 100, 30), "run"))
28         {
29             _animation.Play("run");
30         }
31         if(GUI.Button(new Rect(300, 0, 100, 30), "jump_pose"))
32         {
33             _animation.Play("jump_pose");
34         }
35         //使用融合来播放动画
36         if(GUI.Button(new Rect(0, 30, 100, 30), "idle"))
37         {
38             _animation.CrossFade("idle");
39         }
40         if(GUI.Button(new Rect(100, 30, 100, 30), "walk"))
41         {
42             _animation.CrossFade("walk");
43         }
44         if(GUI.Button(new Rect(200, 30, 100, 30), "run"))
45         {
46             _animation.CrossFade("run");
47         }
48         if(GUI.Button(new Rect(300, 30, 100, 30), "jump_pose"))
49         {
50             _animation.CrossFade("jump_pose", 0.1f);
51         }
52     }
53 }

AssetBundle加载

打包

使用下面的脚本打包:

 1 using UnityEditor;
 2 using UnityEngine;
 3
 4 public class CreateAllInOneAB
 5 {
 6     [MenuItem("Tool/CreateAllInOneAB")]
 7     private static void Create()
 8     {
 9         BuildPipeline.BuildAssetBundle(null, new[]
10             {
11                 AssetDatabase.LoadAssetAtPath("Assets/Resources/Standard Assets/Character Controllers/Sources/PrototypeCharacter/Constructor.FBX", typeof(GameObject))
12             },
13             Application.streamingAssetsPath + "/AllInOne.assetbundle",
14             BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.UncompressedAssetBundle,
15             BuildTarget.StandaloneWindows64);
16     }
17 }

加载

将下面的脚本绑定到摄像机即可:

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class AllInOneAssetBundleLoad : MonoBehaviour
 5 {
 6     private Animation _animation;
 7
 8
 9     void Start()
10     {
11         AssetBundle assetBundle = AssetBundle.CreateFromFile(Application.streamingAssetsPath + "/AllInOne.assetbundle");
12
13         GameObject go = assetBundle.Load("Constructor", typeof(GameObject)) as GameObject;
14
15         GameObject man = Instantiate(go) as GameObject;
16         _animation = man.animation;
17     }
18
19     void OnGUI()
20     {
21         //直接播放动画
22         if(GUI.Button(new Rect(0, 0, 100, 30), "idle"))
23         {
24             _animation.Play("idle");
25         }
26         if(GUI.Button(new Rect(100, 0, 100, 30), "walk"))
27         {
28             _animation.Play("walk");
29         }
30         if(GUI.Button(new Rect(200, 0, 100, 30), "run"))
31         {
32             _animation.Play("run");
33         }
34         if(GUI.Button(new Rect(300, 0, 100, 30), "jump_pose"))
35         {
36             _animation.Play("jump_pose");
37         }
38         //使用融合来播放动画
39         if(GUI.Button(new Rect(0, 30, 100, 30), "idle"))
40         {
41             _animation.CrossFade("idle");
42         }
43         if(GUI.Button(new Rect(100, 30, 100, 30), "walk"))
44         {
45             _animation.CrossFade("walk");
46         }
47         if(GUI.Button(new Rect(200, 30, 100, 30), "run"))
48         {
49             _animation.CrossFade("run");
50         }
51         if(GUI.Button(new Rect(300, 30, 100, 30), "jump_pose"))
52         {
53             _animation.CrossFade("jump_pose", 0.1f);
54         }
55     }
56 }

模型动画分开存放的情况

还有一种情况是模型和动画是分为多个FBX文件存放的,比如下面是模型文件:

虽然有一个Take 001的动画,但是实际上我们并不使用该动画,而是使用下面仅保存了动画的FBX文件:

Resources加载

首先我们要清楚的是,无论是保存了模型还是保存了动画的FBX文件在Unity看来都是同样的一种类型,即添加了Animation组件的GameObject,下面我们看看如何在Resources中加载并显示这个角色,代码如下,挂载到主摄像机即可:

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class ResourcesLoad : MonoBehaviour
 5 {
 6     private Animation _animation;
 7
 8     void Start()
 9     {
10         GameObject go = Resources.Load<GameObject>("ZombieNurse/Zombienurse_Rig");
11
12         GameObject man = Instantiate(go) as GameObject;
13         _animation = man.animation;
14
15         //添加动画剪辑
16         _animation.AddClip(LoadAnimationClip("ZombieNurse/Animation/[email protected]"), "attack");
17         _animation.AddClip(LoadAnimationClip("ZombieNurse/Animation/[email protected]"), "death");
18         _animation.AddClip(LoadAnimationClip("ZombieNurse/Animation/[email protected]"), "idle");
19         _animation.AddClip(LoadAnimationClip("ZombieNurse/Animation/[email protected]"), "run");
20
21         _animation.Play("idle");
22     }
23
24     private AnimationClip LoadAnimationClip(string path)
25     {
26         GameObject go = Resources.Load<GameObject>(path);
27         return go.animation.clip;
28     }
29
30     void OnGUI()
31     {
32         if(GUI.Button(new Rect(0, 0, 100, 30), "idle"))
33         {
34             _animation.CrossFade("idle");
35         }
36         if(GUI.Button(new Rect(100, 0, 100, 30), "run"))
37         {
38             _animation.CrossFade("run");
39         }
40         if(GUI.Button(new Rect(200, 0, 100, 30), "attack"))
41         {
42             _animation.CrossFade("attack");
43         }
44         if(GUI.Button(new Rect(300, 0, 100, 30), "death"))
45         {
46             _animation.CrossFade("death");
47         }
48     }
49 }

AssetBundle加载

打包

使用下面的脚本打包:

 1 using UnityEngine;
 2 using UnityEditor;
 3
 4 public class CreateAB : MonoBehaviour
 5 {
 6     [MenuItem("Tool/CreateAB")]
 7     private static void Create()
 8     {
 9         BuildPipeline.BuildAssetBundle(null, new[]
10             {
11                 AssetDatabase.LoadAssetAtPath("Assets/Resources/ZombieNurse/Zombienurse_Rig.FBX", typeof(GameObject)),
12                 AssetDatabase.LoadAssetAtPath("Assets/Resources/ZombieNurse/Animation/[email protected]", typeof(GameObject)),
13                 AssetDatabase.LoadAssetAtPath("Assets/Resources/ZombieNurse/Animation/[email protected]", typeof(GameObject)),
14                 AssetDatabase.LoadAssetAtPath("Assets/Resources/ZombieNurse/Animation/[email protected]", typeof(GameObject)),
15                 AssetDatabase.LoadAssetAtPath("Assets/Resources/ZombieNurse/Animation/[email protected]", typeof(GameObject))
16             },
17             Application.streamingAssetsPath + "/AB.assetbundle",
18             BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.UncompressedAssetBundle,
19             BuildTarget.StandaloneWindows64);
20     }
21 }

加载

将下面的脚本绑定到摄像机即可:

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class AssetBundleLoad : MonoBehaviour
 5 {
 6     private Animation _animation;
 7
 8     void Start()
 9     {
10         AssetBundle assetBundle = AssetBundle.CreateFromFile(Application.streamingAssetsPath + "/AB.assetbundle");
11
12         GameObject go = assetBundle.Load("Zombienurse_Rig", typeof(GameObject)) as GameObject;
13
14         GameObject man = Instantiate(go) as GameObject;
15         _animation = man.animation;
16
17         //添加动画剪辑
18         _animation.AddClip(LoadAnimationClip(assetBundle, "[email protected]"), "attack");
19         _animation.AddClip(LoadAnimationClip(assetBundle, "[email protected]"), "death");
20         _animation.AddClip(LoadAnimationClip(assetBundle, "[email protected]"), "idle");
21         _animation.AddClip(LoadAnimationClip(assetBundle, "[email protected]"), "run");
22
23         _animation.Play("idle");
24     }
25
26     private AnimationClip LoadAnimationClip(AssetBundle assetBundle, string path)
27     {
28         GameObject go = assetBundle.Load(path, typeof(GameObject)) as GameObject;
29         return go.animation.clip;
30     }
31
32     void OnGUI()
33     {
34         if(GUI.Button(new Rect(0, 0, 100, 30), "idle"))
35         {
36             _animation.CrossFade("idle");
37         }
38         if(GUI.Button(new Rect(100, 0, 100, 30), "run"))
39         {
40             _animation.CrossFade("run");
41         }
42         if(GUI.Button(new Rect(200, 0, 100, 30), "attack"))
43         {
44             _animation.CrossFade("attack");
45         }
46         if(GUI.Button(new Rect(300, 0, 100, 30), "death"))
47         {
48             _animation.CrossFade("death");
49         }
50     }
51 }

时间: 2024-11-08 19:21:18

Unity3D之Legacy动画系统学习笔记的相关文章

Unity3D之Mecanim动画系统学习笔记(二):模型导入

我们要在Unity3D中使用上模型和动画,需要经过下面几个阶段的制作,下面以一个人形的模型开发为准来介绍. 模型制作 模型建模(Modelling) 我们的美术在建模时一般会制作一个称为T-Pose(及双臂张开)的模型. 骨骼绑定(Rigging) 在之前制作的模型上进行骨骼的绑定,我们需要注意的是骨骼数量不能少于15根,同时要遵循Unity3D的骨骼制作标准,如下: http://docs.unity3d.com/Manual/Preparingacharacterfromscratch.ht

Unity3D之Mecanim动画系统学习笔记(一):认识Mecanim动画系统

Mecanim简介 Mecanim动画系统是Unity3D4.0开始引入的一套全新的动画系统,主要提供了下面4个方面的功能: 针对人形角色提供一套特殊的工作流. 动画重定向的能力,可以非常方便的把动画从一个角色模型应用到其他角色模型之上. 提供可视化的Animation编辑器,可以方便的创建和预览动画片段. 提供可视化的Animator编辑器,可以方便的管理多个动画切换的状态. 工作流 模型的准备 Unity不能制作3D模型和进行骨骼绑定,这些需要在专业的建模软件中由美术进行制作,一般常用的建模

Unity3D之Mecanim动画系统学习笔记(九):Blend Tree(混合树)

认识Blend Tree 我们在Animator Controller中除了可以创建一个State外还可以创建一个Blend Tree,如下: 那么我们看下新创建的Blend Tree和State有什么区别: 唯一的区别就是Montion指向的类型变成了Blend Tree类型,那么一个Blend Tree其实也就是一个状态,和状态不同的地方就是一个状态只能设定一个动画,而一个Blend Tree则可以设定为多个动画的混合. 混合树是Mecanim动画系统中比较复杂的一个内容,且其分为多个维度,

Unity3D之Mecanim动画系统学习笔记(七):IK(反向动力学)动画

什么是IK? IK(Inverse Kinematics)即反向动力学,即可以使用场景中的各种物体来控制和影响角色身体部位的运动,一般来说骨骼动画都是传统的从父节点到子节点的带动方式(即正向动力学),而IK则倒过来,由骨骼子节点带动骨骼父节点,具体情况比如人物走路踩到了石头就需要由脚的子节点来带动全身骨骼做出踩到石头的响应. IK可以使人物和场景更加贴合,从而达到更加真实的游戏效果,如果大家玩过<波斯王子>或<刺客信条>系列,应该对主角的攀爬和飞檐走壁的能力印象深刻,这些都是应用了

Unity3D之Mecanim动画系统学习笔记(十):Mecanim动画的资源加载相关

资源加载是必备的知识点,这里就说说Mecanim动画的资源如何打包及加载. 注意,Unity4.x和Unity5.x的AssetBundle打包策略不一样,本笔记是基于Unity4.x的AssetBundle进行打包的. 我们一般使用FBX类型的模型及动画文件,而动画文件的储存一般有两种情况,一是所有的动画和模型都一起存放到一个文件中,还有一种情况是模型单独一个文件而动画单独一个文件.这里我们就两种情况都看一下. 使用的资源是Unity3D自带的以及从一本教材中取出的两种类型的动画资源,同时需要

Unity3D之Mecanim动画系统学习笔记(五):Animator Controller

简介 Animator Controller在Unity中是作为一种单独的配置文件存在的文件类型,其后缀为controller,Animator Controller包含了以下几种功能: 可以对多个动画进行整合: 使用状态机来实现动画的播放和切换: 可以实现动画融合和分层播放: 可以通过脚本来对动画播放进行深度控制: 下面我们通过一个图来直观的看看动画的组成结构: Animator组件用来控制人物动画的播放,其中需要的两个最核心的内容就是控制动画播放逻辑的Animator Controller以

Unity3D之Mecanim动画系统学习笔记(三):Animation View

动画组件之间的关系 我们先看一张图: 这里我们可以看到,我们在GameObject之上绑定的Animator组件是控制模型进行动画播放的. 而其属性Controller则对应一个Animator Controller文件,该文件可以在Animator窗口中打开,其是被设计为状态机形式的系统,多个状态之间的切换关系可以在该界面进行设置. Animator Controller中的每个状态则对应一个Animation Clip,每个Animation Clip是一个简单的动画单元,可以在Animat

Unity3D之Mecanim动画系统学习笔记(四):Animation State

动画的设置 我们先看看Animation Clip的一些设置: Loop time:动画是否循环播放. 下面出现了3个大致一样的选项: Root Transform Rotation:表示为播放动画的对象的旋转方面的信息. Root Transform Position(Y):表示为播放动画的对象的位置 y 轴方面的信息. Root Transform Position(XZ):表示为播放动画的对象的位置 XZ 平面方面的信息. 他们都有一致的选项,我们逐个的来看: Bake Into Pose

Unity3D之Mecanim动画系统学习笔记(八):Animator Layers(动画分层)

解决什么问题? 动画分层可以用来解决什么样的问题呢?试想一下如果你要开发一款第三人称的射击游戏,那么肯定是希望身体的动画分为上下两部分,上方根据瞄准的位置和是否射击进行动画播放,下方根据移动播放动画.最好的例子就是Unity4.x自带的示例AngryBots了. Avatar Mask 下面我们就使用Avatar Mask来实现人物在奔跑中招手的效果. 我们先添加一个人物到场景,同时为其添加一个Animator Controller并设定好跳转条件,如下: 接下来我们添加下面的脚本来控制动画的播