在上一篇,我们介绍了有关Animation这个类中的部分方法,我后来想了想,这么介绍也不是个办法(其实有些方法我自己也没用过),该介绍点实际的东西了,毕竟我们是要做东西出来的。那好,我们就开始吧。
首先我们要介绍的主题是:Animation Blending ,即动画融合。我们来看官方文档上的描述: 用我自己的理解就是:在现今的游戏中,动画融合是一个必不可少的特性用以让你的的角色能够产生平滑的动画。动画设计师首先为角色创建了一些个动画片段,例如一个行走循环,跑步循环,还有站立或射击的。在你运行游戏期间,你需要从站立的动画状态转换到行走的动画状态并且看上去要足够平滑,不能突然跳转。 此时我们就需要 有一种处理方式来完成我们所想要实现的效果。这就是“动画融合”的用处。在Unity中,一个角色可以有多种不同的动画片段,Unity可以将这些动画片段融合起来并以一种组件的形式(即Animation)进行管理,并根据具体情形来比如脚本来生成最终的动画。看来我们其实一直在运用“动画的融合”。 using UnityEngine; public class SuperMarioAnimation : MonoBehaviour { AnimationState jump = animation["jump"];//暂存“jump”的动画状态,记住,是暂存。仅仅只是用于下面三行代码中的动画设置。 jump.layer = 1 ;//设置动画状态jump的动画层值为1,相对于默认层级值要高,为的是有更多的优先级取得动画权重。 jump.enabled = false;//暂停该动画的播放,这个我会在后面进行相应的讲解,因为它有其独特的应用情景。 jump.wrapMode = WrapMode.Clamp;//设置动画状态jump的循环模式为Once(单次,上一篇已经证明了)循环。 float currentSpeed = marioController.GetSpeed(); public void DidLand()//SendMessage方法调用的,在goober着地时执行 注意,要想理解好这段代码,我们必须结合另外一个加在goober上的脚本:SuperMarioController。这个例子里面出现了我们之前提到的一个非常重要的类:AnimationState,即动画状态,还涉及到了动画层的概念。所谓动画层,即AnimationState.layer,AnimationState这个类中的一个很重要的属性。在Unity的动画体系中,默认情况下,所有动画状态的layer值为0,你可以在脚本中动态的调节该动画状态的layer值。如上代码,我们在unity3d中点击运行按钮,我们什么都不做时,由于此时获得的currentSpeed的值肯定是小于0.1的,那么此时goober就会播放idle(站立)动画,见: 但是当我们按下了空格键,此时就会立即播放跳跃动画。假如我们将不设置jump的layer值为1,即注释掉这行: 我们再运行工程,此时我们还是按下空格键,效果如下: 错误定位到了: 出错了,为什么呢?由于此时没有设置跳跃动画的layer,导致跳跃动画的layer与idle的layer的值都为0,拥有同样的播放优先级,所以按下空格键时准备播放跳跃动画,但是在下一帧时程序发现此时从marioController 脚本组件中得到的currentSpeed变量的值小于0.1,所以又转为播放idle动画,可是此时在此动画脚本中执行到了上面蓝先的这一行,发现lastJump此时是空的(因为此时没有播放跳跃动画嘛),于是才提示空引用错误。所以工程此时就会暂停,我们可以从上面这张图中得以发现,看,goober此时是不是停在半空中,程序是不是暂停运行了?总结一下:如果某个动画状态的layer越高,执行起来就会比layer值较低的动画状态优先,且只有此动画状态被Stop或暂停时才有可能执行其他动画状态。官方的一个说明是: Lower layer animations only receive blend weights if the higher layers didn't use up all blend weights. |