动画是一款游戏不可缺少的一部分。在unity中,我们可以直接使用unity自带的动画系统来制作我们想要的动画,其操作相当便捷。
帧动画是2d像素游戏的主流,我将以帧动画为例记录我最近学习动画系统的一些收获。
unity的动画系统有三个不可缺少的部分。第一,动画;第二,动画组件;第三,动画控制器。
动画和动画组件不难理解,动画是我们添加进unity的资源文件,动画组件是添加进游戏物体的必要控件。
那么动画控制器是什么呢?
那不就是能控制动画的系统。
没错,但是如何控制呢?
首先我们需要知道为什么要有动画控制器这个东西。unity中的动画和我们日常生活中理解的动画不太一样。在unity中,动画是由一个个“动画片段”组成的,而不是我们小时候长达24分钟不间断的动画片。为了将这些“动画片段”组装成我们想要的动画,就需要动画控制器来判断各个动画片段什么时候该播放,什么时候不该播放。
也就是说,动画控制器其实就动画片段的播放流程控制器。
下面以实际的游戏工程来介绍unity动画系统,涉及人物的移动,跳跃动画。
首先,我们需要为人物添加动画组件animator。
第一个参数是animation controller,即动画控制器。
第二个参数是替身,我们做2d游戏的时候不需要关注这个。
其余的参数可以通过unity代码手册查阅,本篇笔记不做修改。
有了动画组件,我们就需要一个动画控制器来绑定它。
在project窗口右键create -> animation controller。
可以在animator窗口查看该控制器的具体内容(windows->animation->animator)。
其中,entry指动画开始,通常后面会接一个默认动画。
any state指任何状态,后面接的动画任何状态都能跳转到。
exit即退出,退出之后又会回到entry。
将动画控制器拖入animator组件中。
这样就完成了动画控制器和动画组件的绑定。
还记得unity动画系统的三大组成部分吗?
动画,动画控制器,动画组件。
现在有控制器和组件,只缺动画了。
unity为我们提供非常便捷的动画制作方式,通过连续播放一组图片从而达到动画效果。
接下来制作人物默认状态下的动画片段。
点击create,选择好文件夹,创建人物第一个动画片段吧。
按住shift,选择一组图片拖入animation中,一个动画片段就已经做好了。怎么样,是不是很简单?
修改采样率samples,采样率越低,动画播放得越慢,通过不断调试来找到适合我们的采样率。
点击播放符号即可在场景中预览动画,每次预览完记得点一下preview,结束预览状态。
一个动画片段显然不够我们使用,接下来我将需要的动画片段一次性创建好。
现在动画控制器中已经有了刚刚创建好的动画片段了。
先将playerjump删除,专注设计奔跑动画的逻辑关系。
右键playeridle,选择make transition,创建一条过渡(转换)指示线,将其连接到playerrun,即人物奔跑的动画片段。
点击这条新建的转换指示线,可以设置其中的转换条件。
这个转换条件可以在parameters中添加。
点击加号,可以看到有四种不同的转换条件类型,分别是浮点型,整型,布尔型和触发型。
现在不妨来思考一下我们什么时候需要播放人物动画。
没错,就是人物移动的时候。
那么和人物移动相关的变量有哪些可以作为条件变量的值呢?
速度是个不错的选项。
如果速度大于0,那么就播放人物动画。
有了想法,接下来就是实现了。
首先在parameters中添加一个浮点型的参数velocityx。
接着选择转换指示线,将刚刚添加的参数加载进去。
同时建立一个playerrun返回playeridle的转换指示线,条件相反。
这里有两个小问题。
第一个问题,我们的移动应该是连续不断的,不会随着动画的结束而恢复到默认状态。
因此,我们需要取消勾选has exit time,让该动画完全受控于转换条件。
同时也可以取消过渡时间(如果值大于0会出现延迟效果)。
第二个问题,unity在将一个变化的值和0比较时可能会出现一些小错误,为了减少这种错误,我们可以将播放动画的条件设置为velocityx大于0.1。
下面最后修改过后的设置图。
那么velocityx的值究竟如何和速度进行绑定呢?
现在就需要我们自己写脚本了,我在这里为人物新建了一个playeranimation脚本,专门管理动画相关的代码。
思考我们需要获取哪些组件和变量。
首先是动画组件,只有获取动画组件才能为velocityx的值赋值。
其次是刚体组件,我们需要将刚体中x轴的速度传递个velocityx。
代码如下:
using system.collections;
using system.collections.generic;
using unityengine;
public class playeranimation : monobehaviour
{
private animator anim;
private rigidbody2d rb;
private void awake()
{
anim = getcomponent<animator>();
rb = getcomponent<rigidbody2d>();
}
private void update()
{
anim.setfloat("velocityx", mathf.abs(rb.velocity.x));
}
}
setfloat方法的意思是将刚体x轴速度的绝对值传给velocityx,除了setfloat外,还有setbool、setint和settrrigger,除了settrigger,其余的都有两个参数,第一个参数是条件参数的名称,第二个参数是要传递的值。由于这个值需要实施检测,因此放在update()中。
现在我们的人物已经可以自由奔跑了,接下来制作跳跃动画。
与奔跑动画不同,跳跃动画由4个不同的动画片段共同组成,每个动画片段表示一个跳跃的阶段。
在这种情况下,我们可以直接使用unity自带的一个十分方便的操作——混合树(blend tree)。
在动画控制器中右键新建一个混合树。
点击混合数,在inspector窗口中的添加四个motion。
每个motion对应一个跳跃的动画片段。
新建一个条件参数velocityy,记录y轴方法人物的运动速度,并将parameter修改为velocityy。
注意到现在动画片段的切换门槛不可以手动修改,这是因为我们选中了automate threshold,将其取消勾选就可以手动修改了。
接着仿照移动动画在脚本中添加velocityy的赋值就行了。
using system.collections;
using system.collections.generic;
using unityengine;
public class playeranimation : monobehaviour
{
private animator anim;
private rigidbody2d rb;
private checkstate checkstate;
private void awake()
{
anim = getcomponent<animator>();
rb = getcomponent<rigidbody2d>();
checkstate = getcomponent<checkstate>();
}
private void update()
{
anim.setfloat("velocityx", mathf.abs(rb.velocity.x));
anim.setfloat("velocityy", rb.velocity.y);
anim.setbool("isground", checkstate.isground);
}
}
这样,跳跃动画就做好了。
发表评论