2012-11-29 17:09:33 Sparrowfc 阅读数 18090
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

用Unity3D也算是好久了,但是每次做项目总还是能学到新的东西。这次做一个TPS的项目就遇到了这样一个问题,如何同时在上下半身播放不同的动画?解决方法其实是很简单,但由于对于动画资源的了解不足导致问题不断,最后是彻彻底底的研究了一遍Unity3D的动画系统(Legacy),虽然4.0出了新的动画控制系统,使用了一下功能相比原来确实强大不少,但还是将这次对于原先的动画系统的学习总结记录下来,毕竟这些动画的概念与策略是通用的,而且因为4.0在mac上目前貌似还没有破解所以项目还是得在3.5上做。相信对于深入理解新的动画系统也会很有帮助。

一、Unity3D动画系统相关类

1.1 AnimationClip

AnimationClip是Unity3D中播放动画的最基本对象,通过FBX导入的各个动画对象其实就是一个AnimationClip。这个类已关键帧的形式记录了骨骼关节在各个时间节点上的位置、旋转信息,根据帧频率frameRate结合播放模式wrapMode通过插值计算即可播放出连续的骨骼动画。

1.2 AnimationState

每个AnimationState包含了一个AnimationClip,并记录这个动画片段的一些播放控制属性,实际上是一个AnimationClip的包装器。

其中比较重要的参数有layer,weight, enabled, speed, blendMode这几项。这些参数的具体含义将在自定义混合动画控制中详细解释,在简单的动画控制时并不需要对AnimationState进行直接操作。

1.3 Animation

Animation是Unity3D的动画播放控制组件,包含了一系列的AnimationState对象,提供各种动画播放及控制方法。常用方法有Play(), CrossFade(), Stop()。在脚本中通过animation即可直接引用同一物体上的Animation控件。


二、简单动画播放控制

所谓简单动画播放控制就是同一时间只有一个动作,比如Standard Assets中的那个水管工,静止idle,走walk,跑run,跳跃jump,攻击attack这些动作都是全身动作,同一时间只应该做一种动作,只有在动作切换时需要将两种切换动作进行混合以达到平滑过渡的效果,以上的操作使用Animation提供的CrossFade()方法即可达到。无论是CrossFade还是Play理论上都只需要在切换动画时调用一次即可,当然重复的调用并不会影响动画的播放,当Unity3D检测到当前播放的动画与函数调用使用的动画一样后会忽略该次调用。


三、自定义混合动画控制

3.1 多动画同时播放的需求

在大多数情况下简单的动画播放控制已经足够,然而当游戏变得复杂时,单动画播放带来的问题就是美术工作量的急剧增加。

最为典型的就是第三人称射击(动作)游戏,通常来说游戏中的人物会有各种上身动作如瞄准、射击、换子弹等,而下身则对应站立,行走(通常还是四个方向的行走动作)。这时候如果只能播放一个动作的话就需要美工制作大量的动作(站立瞄准、站立射击、跑步瞄准、跑步射击等等),其工作量可想而知。显然,最为效率的方式是美工分别做出上半身以及下半身的动作,然后由程序根据游戏角色的操作将两者动作混合起来同时播放。而这就涉及到了多动画同时播放的需求。此时简单的CrossFade()方法已经不能满足了,我们需要通过AnimationState来对动画播放进行自定义的控制。

3.2 使用AnimationState控制动画播放

Unity3D的动画播放实际上都是通过AnimationState来进行控制的,Animation组件中提供的CrossFade,Play等方法其实就是将一系列对AnimationState参数进行设置的操作进行了封装。

其中主要相关的参数有四个:

layer: 该动画片段(AnimationClip)所在的播放层次。

weight: 该动画片段在动画混合中所占的权重(0~1)

enable: 该动画片段是否进行播放

blendMode: 混合方式,有两种Blend和Additive

默认初始化情况下Animation组件中的全部AnimationState的layer=0,weight=0, enable=false。Animation组件默认播放的AnimationState的layer=0, weight=1, enable=true。

 

一、Unity3D动画播放策略

Unity3D在进行动画播放时按照下面的策略进行:

1.找到最高一层的全部AnimationState

2.将其中enable为true且weight > 0的AnimationState中的clip加入混合池(虚构的一个概念)

3.如果当前混合池中全部blendMode为Blend的clip的权重相加少于1,则找到下一层的全部AnimationState。重复2.

4.对混合池中的全部clip进行混合操作,生成最终的动作。

在进行最终混合时所有clip的实际权重会进行归一化处理,即相加为1,处理时根据blendMode的不同结果也会有所差异,下面的例子会进一步说明。

 

二、使用AnimationState控制播放的实例

举几个实际的例子对Unity3D的动画混合策略进行说明。对于AnimationState的设置全部放在Start或Awake中进行。并且注意把Animation组件中的默认播放动画设为None,取消选中Player Automatically,原因正如前文所述,默认播放的AnimationState参数初始值与其他State不同,会对实验造成影响。

1. 同一层动画的混合播放

AnimationState right= animation[“run_right”];

AnimationState idle= animation[“idle”];

right.layer = 1;right.weight = 1; right.enable = true;

idle = 1; idle.weight= 1; idle.enable = true;

 运行结果是角色动画介于行走与静止之间,体现两个动画1:1的混合效果

2. 高层动画覆盖下层动画

 right.layer = 1; right.weight = 1;right.enable = true;

idle = 0; idle.weight = 1; idle.enable = true;

 运行结果是角色行走

3. 高层动画与下层动画混合

right.layer = 1; right.weight = 0.5f; right.enable = true;

idle = 0; idle.weight = 1; idle.enable = true;

运行结果与1相同,idle的实际weight为1 * (1 – 0.5f)

4. 使用Additive混合不同层动画

right.layer = 1; right.weight = 1; right.enable = true;

right.blendMode = BlendMode.Addictive;

idle = 0; idle.weight = 1; idle.enable = true;

 运行结果与1相同,idle的实际weight为1/(1+1)

 

三、其他的动画播放控制参数

speed: 控制动画播放速度,比如调整射击速度就是将该值提高

time: 当前动画所在时间点

warpMode: 动画循环方式,有一次、循环、镜像循环PingPong

3.3 自定义动画过渡

动画过渡实际上就是两种动画混合权重的过渡,前一种动画的权重由1渐变为0,后一种由0变为1,由此实现动画的平滑过渡。在实际操作时,并不需要过渡时在Update()中每帧去调整两种动画AnimationState的权重weight。Animation控件提供了Blend()方法帮助在后台自动计算这种过渡,其使用方法与CrossFade类似,详见Unity3D的script手册。

3.4 Play(), CrossFade()背后的操作

了解这些基本方法背后进行的操作在同时使用AnimationState对动作进行控制时十分有用。

首先是Play(stringanimationName)(Play() = Play(default Animation name))这个方法实际上是将animationName所在层的全部其他AnimationState的weight置为0,enable置为false,将animationName的weight置为1, enable置为true。

CrossFade()与Play()大致相同,只不过他并不直接将其他的AnimationState的weight置为0,而是调用Blend()方法将其向0进行渐变,一旦该AnimationState的weight变为0再将其enable设置为false。

由此可见,当你设置了多层AnimationState后,仅仅调用这两个方法很可能并不能达到你想要的动画控制效果。当然,这两个方法最后有一个默认参数PlayMode来调整执行策略(区别就在于操作对象仅仅在该层还是全部AnimationState对象),总之这一节通过阐述Play与CrossFade背后的操作,希望使我们在使用AnimationState进行混合动画控制编程时能够正确的使用这两个方法以达到期望的效果。

3.5 局部动画

以上所介绍的AnimationState操作只是多动画的手动播放及混合控制,还并没有涉及到如何向开头所讲的上下半身播放不同的动画。要在同一个角色上同时播放两个不同的动作使用局部动画即可。

一、生成局部动画

在Unity3D中有两种方式实现局部动画,一是使用AnimationState的AddMixingTransform方法,该方法传入一个骨骼节点的Transform,调用后该动画片段AnimationClip便只会影响该节点及其子骨骼,而对其他骨骼关节并不再影响。

另一种方法是在动画模型制作时就只对局部的骨骼制作动画,其他骨骼在整个动画片段中都保持不变,这样生成的动画片段AnimationClip中就不会包括对那些不变骨骼的关键帧信息,也就不会对其他骨骼关节进行影响。(这是我根据动画播放的实际控制结果进行的推测,在Unity3D的官方文档中好像并没有直接说明,仍需查证)

了解第二种方法十分重要,虽然还只是推测。因为在与美术沟通前你可能并不知道导入的是一个局部动画,而将其当成全身动画,使得在进行动画混合控制时产生了意想不到的结果。我在一次项目中发现明明角色应该进入idle状态,但是双腿仍然在跑动,为此花了两天时间查证,也是直接促成了这篇文章的诞生,最终发现原来美术给的idle只有上半身有动画,下半身没有,因此虽然idle比跑动高一层,但下半身并不能覆盖。

 

二、局部动画的混合

局部动画的混合策略与前述Unity3D动画播放策略相同,只不过只是影响局部骨骼。这也就是说,上半身与下半身的动画无论谁所在的层更高,权重多少都不会影响另外半身的动画播放。但是上层的半身动画会覆盖下层的全身动画或与之混合,而全身动画中不包含在半身动画中的骨骼则完全不受影响。


四、射击类游戏应用

参考Unity3.5的官方例子Angry Robot。在这个例子中很好的实现了上下半身的独立旋转,射击动作与跑步动作的半身分离。这一节以此作为样例进行分析。

动作资源:

run_forward,fun_backward, run_left, run_right。四方向的跑动,全身动作,全部置于第1层。

Idle。静止,全身动作,位于第2层。

Attack。攻击,半身动作,位于第4层。混合方式Additive

操作控制:

初始化,全部动作的weight置为1,Attack的enable置为false,其余为true。这样初始状态下Attack不播放,Idle覆盖跑动动作,角色表现为静止站立动作。

移动时将Idle的weight根据速度向0渐变,开放跑动动作。使用CrossFade()在四个跑动动作中选择合适的动作进行播放。停止时再将Idle的weight逐渐置为1,重新覆盖跑动动作。

攻击时将Attack的enable置为true,停止攻击时置为false。由于Attack动作在最高层,且混合模式为Additive,因此站立攻击时Attack动作与行走动作上半身进行混合,跑动攻击时Attack动作与跑动动作上半身进行混合。


2015-07-07 21:32:11 huiyihgy 阅读数 1152
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

三维动画一般在三维动画软件中制作,游戏引擎中也有自己所谓的gameobject的抽象。那么这两者之间有什么关系呢?具体来说,动画是否会影响游戏对象的位移和旋转(root motion)?

这里有两个概念要区别开来:
第一个是身体变换(body transform 或者叫做 bake into pose)。
什么是身体变换呢?身体变换属于三维软件,全部都在世界坐标系中产生,是动画师在三维软件中调出来的。
第二个是根变换(root motion)。
根变换属于游戏引擎,使用角色在Y=0平面的映射偏移去计算出每一帧需要进行的偏移,是引擎从三维软件导出的数据算出来的。因为三维软件导出的肌肉曲线和IK解算是局部坐标系的,没有世界坐标系的Y平面的移动,所以三维软件增加了一个通道作为Y平面的偏移,然后引擎每帧主动算出来那些Y的值,叠加到游戏中的动画中。

具体来说,在unity3d中有以下的一些组合来表示。
Bake Into Pose: 保持根变换不变,使用动画的位移和转向,看起来是在播放动画,实际上引擎中的游戏对象位移和旋转并没有发生变化
不Bake Into Pose.:如果动画产生了旋转,Y平面,XZ平面的变化,将影响到根变换
Base Upon: 设置动画的依赖。。

Apply root motion + root transform: 引擎中的游戏对象的位移和旋转在动画播放的每一帧都始终发生变化。
Apply root motion + bake into pose(body transform): 引擎中的游戏对象的位移和旋转在动画播放过程中不会发生变化。只有动画播放结束了,游戏对象才会一次性的到达动画最后一帧的位移和旋转。
No Apply root motion + bake into pose(body transform) : 动画一直播放,但是引擎中的游戏对象的位移和旋转不会发生变化. 如果开始一个新的动画,模型立即回到起始位置。
No apply root motion + root transform: 模型保持不变。

关键就是区别3dmax/maya中导出的动画和游戏引擎中的游戏对象的互动关系。

2016-04-03 15:52:33 zzlyym 阅读数 1098
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

        帧动画制作过程。

1:把几张图片拖到项目中,全选,改变它们的属性类型为精灵图,如图所示,之后apple应用一下。

2::精灵图全选,拖到Hierarchy中,这时会自动创建一个Animation的文件,我在场景中改名为Animation,这时你会发现精灵图的旁边出现了两个东西,如下图,第一个是控制动画的,第二个是动画。


3:可能初始图片不是我们想要的,这时选中Animation,如图属性中更改第一张显示的图片。

4:如果只让他播放一次,选中,looptime勾点掉,如果想改变他的播放速度,选中动画控制,属性点击open,出现下图的东西,选中,右边属性有个speed,数值越小,播放速度越慢。有错或者需要注意的地方请指出,谢谢了。


2017-04-28 23:00:36 u014133338 阅读数 509
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

-骨骼动画
unity中配置状态机,在3Dmax中设置人物动画
导出应该将动画中的烘焙动画和变形勾选,fbx格式为2009格式。在导入unity后,需要对骨骼进行匹配

2014-09-17 10:41:42 huodianyan 阅读数 4578
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

这几天开始做游戏中跟动画相关的部分了,此次新项目我们决定一次从新开始,就是能用新的东西就都用新的东西,没有必要总是把自己局限在之前的认知里头,所以此次我们大胆而又现实的采用了Unity 4.x版本新增的Mecanim动画系统,并且我们果断地又选择了使用Humanoid动画类型。好吧,一切从新开始。

一切从新开始就意味着会有很多新的坑需要自己一个个去填,我们一直都拥有一颗坚强受虐的心不是吗。在我们的动画设计师将骨骼动画调好了之后,给了我一组FBX文件,导入Unity之后,预览一下这个动画吧。

animation-1

animation-2

 

 

 

 

 

 

我们可以很明显得看出这两个动画中人物角色的右手和武器之间的位置关系是不对的,跟动画设计师在3DS Max中制作和预览的效果也不对,好吧,碰到第一个坑,上吧。

通常我们先做的第一件事情就是先查查文档,看看Unity官方是否有一些最佳实践的建议,可是我翻遍了Unity Manual中关于Mecanim Animation System的所有文档没有看到相关的内容,而游戏引擎通常对于开发者来说就是个黑盒,出了问题除了查查看看别人是否碰到同样的问题也就是直接找Support这条路了,或者就是自己各种尝试呗。好吧,那就先Google一下吧,找啊找,找啊找,找了将近两天看了很多跟Mecanim动画相关的问题,但是就是没有找到这个这么基础的问题相关的帖子啥的,简直没有天理啊。

既然Humanoid不行,那我们试试Generic动画吧,这下就都OK了,那么显然动画资源自身肯定木有问题了,这下就确定肯定是Unity按照Humanoid动画导入FBX资源的时候有某些设置我们没有按照要求来做,所以导致了这个武器完全不跟着右手骨骼运动的情况。自己纠结了又一天,又是各种查啊各种试,完全木有进展。最后,只能求助于其他有经验的人了,通过我们的动画设计师,找到了一个他一个做技术美术的朋友,该大牛对Unity非常熟悉,专门解决项目中碰到的技术问题,哪里有问题哪里就有他。直接远程协助一下,看着大神一点点地调整,先是检查了一下Avatar设置中骨骼对应的关系是否正确,确认无误之后,再次运行看看效果依然如此,大牛稍微思考了一下,马上打开了Unity导入动画的页面,找到了Animations标签页,然后展开Mask设置中的Transform节点,将所有未勾选的人物角色骨骼节点都勾选上,然后Apply一下,再次运行游戏,搞定。

animation-3

animation-4

 

 

 

 

 

 

再回顾一下完整的调整过程吧,首先我们要确定我们出问题的骨骼具体是哪根,因为目前看到的现象是右手拿的刀和挂在腰上的刀鞘出现了问题,打开Avatar设置页面,查看一下,确定是Bip001 Prop1和Bip001 Prop2这两根骨骼出了问题。

Bip001 Prop1

 

确定了是这根骨骼出现问题了,然后进入到出现问题的动画文件jin_wei_jun@run.FBX的导入设置页面,打开Animations标签页 =》展开Mask节点 =》 展开Transform子节点 =》 找到左右手对应的刀和刀鞘的骨骼,勾选上,然后点击Apply按钮就好了:

import setting

QQ20140816-6@2x

QQ20140816-7@2x

 

 

 

 

 

 

 

 

 

 

虽然大神帮我们解决了这个困扰了我将近4天的问题,那么究竟为啥捏?其实在被困扰的4天里头,其实也发现了一些蛛丝马迹的,就是每次我们导入动画jin_wei_jun@run.FBX的时候,Unity总会提示以下的警告:

MuscleClip ‘jin_wei_jun@run’ conversion warning: Bone position is different in avatar and animation
‘Bip001 L Thigh’ : position error = 31.473890 mm
‘Bip001 R Thigh’ : position error = 8.405679 mm
‘Bip001 L Clavicle’ : position error = 37.673038 mm
‘Bip001 R Clavicle’ : position error = 76.461647 mm

UnityEditor.DockArea:OnGUI()

和这样的一个警告:

MuscleClip ‘jin_wei_jun@run’ conversion warning: ‘Bip001/Bip001 Pelvis’ is between humanoid transforms and has rotation animation. This might lower retargeting quality.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’ conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine’ is between humanoid transforms and has rotation animation. This might lower retargeting quality.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 L Thigh’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 R Thigh’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001 Neck/Bip001 L Clavicle’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001 Neck/Bip001 R Clavicle’ has translation animation. It is not supported.

UnityEditor.DockArea:OnGUI()

这两个警告大体的意思是啥呢,刚开始自己没有太注意,后来总是找不到原因就想着会不会还就真是这俩警告给弄的呢,自己仔细看了一下。第一个警告的意思,应该说的是动画中有几个骨骼的位置跟这个动画实际使用的Avatar中骨骼的位置不相符,这个原因我大概能理解的原因是这样的。我们在制作的过程中会将模型文件和动画文件分开,我在导入模型文件的时候会创建一个属于这个模型的Avatar,其他的动画都会直接引用这个Avatar文件而不会每个动画都创建自己的Avatar,而不同的动画中人物可以会有一些不同的动作,这就会让动画中角色的一些骨骼位置和模型(模型默认姿态就是站姿)站立姿态时的骨骼的位置会出现一些不匹配的情况,所以这个可以理解了。那么第二个警告呢,这个警告都是说某根骨骼有位移动画和旋转动画,而这些动画会降低Retargeting的质量,同时Humanoid动画不支持在这些骨骼上使用位移动画。虽然这个警告中提到的带有位移和旋转动画的骨骼不少,但是涉及的就是角色躯干、胸部、臀部、左右手、左右脚这几个非常关键的骨骼,并没有提到影响到刀和刀鞘的骨骼Bip001 Prop1和Bip001 Prop2啊。

综合大神提供的解决方案,应该可以初步得出结论,导入FBX动画的时候,选择Humanoid动画类型进行导入的时候,Unity会自行进行计算和判断,然后根据Retargeting最佳原则,设置Animations选项卡中Mask节点下Transform子节点中的骨骼是否需要在Humanoid动画中应用位移动画,而这个时候Bip001 Prop1和Bip001 Prop2这俩骨骼就被忽略了,所以我们需要手动的去勾选,如果有必要的话,那么就把所有的未勾选的骨骼都勾选上,然后再Apply一下吧,如果出现Apply一次不生效的话,重新重复设置遍,然后再Apply一下吧(我自己碰到了一次把所有的都勾选,然后Apply之后无效,重新展开之后发现只有部分被勾选上了,重新再全勾选Apply一次才好的情况)。

刚才我们提到了使用Generic动画的时候就不会出现这个问题对吧,那么为了印证这个结论是否正确,我们可以检查一下Generic动画导入设置页面中Animations标签页中Mask节点下Transform子节点中的骨骼节点是神马情况就好了。如下图,所有的节点默认都是勾选上的。

QQ20140816-10@2x

鉴于此,我们可以得出结论就是,在我们使用Humanoid动画类型导入FBX文件时,Unity会以最佳匹配Retargeting规则的方式自行计算,看看那些骨骼是需要勾选Transform动画选项的,而默认使用Generic动画就会将所有的骨骼节点Transform动画选项都勾选上,所以效果是正确的。OK,所以问题到这里就彻底明了了。


unity3d的动画有这么几个类型 ,

博文 来自: wangbotangbo
没有更多推荐了,返回首页