分享2D Unity游戏的动画制作经验
作者:Alex Rose
Unity近期宣布推出额外的2D游戏支持,加入了Box 2D物理和一个精灵管理器。
但这里还是有些技巧须要牢记在心。逐帧更改图像仅仅是动画制作的冰山一角,若要让你的游戏出色执行。你还得使用转换和旋转等功能。
如今让我们先从基本技巧開始。
更改帧
假设你已经准备好了制作动画的纹理,你可能会使用SpriteManager脚本的付费版本号,或者Unity的新版本号。假设你使用的是2D位面和纹理。这就是一个低效率的方法。但假设你是在制作一个game jam的项目,你可能会想塞入一些可行而好看,但却不一定有效的元素。这也是一种覆盖了全部步骤的全面方法。假设是在精灵管理器中则可能被删除某些步骤。
首先。你将须要一个公开的Texture[] 阵列。所以你能够将纹理拖入到Unity编辑器中的对象。以及一个在Start()中初始化到0的整数currentTexturep。下一步你须要一个像这样执行的NextTexture() 函数:
NextTexture(){
currentTexture++;
if(currentTexture>=textureArray.Length) currentTexture=0;
AnimatedPlane.renderer.material.mainTexture = textureArray[currentTexture];}
有两种简便的方法能够调用这样的函数:协同程序递归和固定间隔。
使用固定间隔是最快的方法(但较不精确)。
你须要一个整数计数器,在你的Start()函数中初始化到0。以及一个FixedUpdate() 函数(游戏邦注:每次都会更新。你能够在Unity时间管理器中自己调整)。
在FixedUpdate()中放置你的条件句(比如if(walking)),并在当中用conter++添加你的计时器,之后设置例如以下声明:
if(counter>=animationDelay){
counter=0;
NextTexture();
}
这里的animationDelay能够是你自己选择的随意值。
这将以持续速度(取决于你在Unity时间管理器中设置的速度)推进帧。
第二个方法是使用递归。但这一方法的劣势在于不易处理条件句,但你还是可以获得所须要的准确延时。假设你想让特定帧延长或缩短。这一方法就尤其管用。你须要一个IEnumerator TextureChanger() 以及to StartCoroutine(TextureChanger()) in Start().
IEnumerator TextureChanger(){
yield return new WaitForSeconds(timeInterval);
if([conditions]) NextTexture();
}
这里timeInterval也是你自己选择的随意值。有了这些函数,你就能够将随意数量的纹理拖到GameObject,这样仅仅要你提供正确的条件,它就会正确执行动画。
如今让我们做一些更有趣的操作。
平滑移动到一个点
下面公式是制作Unity 2D动画的一个诀窍:
where 0 < slidespeed < 1. I recommend 0.1f as a good slidespeed value.
这个公式同意你把对象完美移动到一个点。在滑动GUI、角色控制、关卡生成、摄像尾随、褪色/移位等操作中尤其管用。
这是我即将公布的新游戏《Rotation Station》中的一个高级版本号,是从一个较低点移到一个较高点,最后变成一个小泡。
每一个贴图都会依据该公司向下移动,但每一个贴图都有随机的延时。随机的初始化旋转(也使用这一公式旋转至它所期望的方向)。
关于角色控制的样例能够參考我近期推出的《Rude Bear Radio》,在这个项目中,该公式运用于制作流畅的鼠标控制方法。
那么,让我们看看怎样将其运用于上述样例。
首先,我们须要知道鼠标位于2D区域。为了找到它。我们要先将这个代码放置于滑动GameObject的FixedUpdate()函数中:
Vector3 MousePosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, transform.position.z-Camera.main.transform.position.z));
这里使用了鼠标的X和Y轴位置,以及从摄像机到滑动GameObject的距离来确定鼠标的2D位置和3D坐标。如今我们要从这个环节的开端来调整该公式。所以。要记住Unity中的2D步骤。
transform.position += new Vector3((MousePosition.x-transform.position.x),
(MousePosition.y-transform.position.y),0)*slidespeed;
你就仅仅要这两行代码就搞定了。至于GUI这类东西。你能够在之后编写一个声明:
if(Mathf.Abs(finalvalue-currentvalue)
让我们再看还有一个样例。《Rude Bear Radio》中的困难模式Mario台阶。
当中的背景使用下面公式由黑变白:
background.renderer.material.color =
(1-factor)*background.renderer.material.color+factor*desiredcolor;
你从中能够看到它遵从的基本形式,简写就是Next = current+(final-current)*factor。代码会检查R值是否处于一定的色彩范围,假设是,它就会更改factor。令其更为迅速地褪色。假设R值很接近于1。它就会将其所需颜色设置为黑。你还能够检查下R、G和B,并以一个阵列推进颜色。你能够在我的第二个案例项目《Rude Bear Rising》的背景中看到这样的样例。
眼下来看,这些都非常easy,你能够照搬公式做。而下一步操作则须要考虑很多其它因素。
三角法和数学的重要性
三角法对动画制作来说很重要。就算有了优秀的帧,也不一定可以令它们看起来生动漂亮,有时候你根本不须要帧就能做事。
比如,我首次进入Ludum Dare工作室时,我的室友就给我画了几张图。我至今仍然记得当中的每一个角色,用什么方法呢?像木偶一样将角色绑在棍子上操作。
这样的移动方式很easy。转换时用正弦(sin)。旋转时用余弦(cos)。
为了创造这样的动画。你要让波纹停止并在你松手和输入时继续,否则这样的动作就会极端分散。
所以你须要一个首要变量(即我所谓的walkbob)。仅仅要对象还在移动,它就会在FixedUpdate中添加Time.deltaTime。之后就制作你的函数:
translation = maxHeight*Mathf.Sin(speed*walkbob);
rotation = maxRoll*Mathf.Cos(speed*walkbob/2);
然后将位置和旋转设为这些值(比如transform.position = new Vector3(transform.position.x,translation,transform.position.y))。
这能够处理类似那种动作。可是另一种动画须要考虑很多其它因素。这就是我所谓的三角舞,它用于制作可爱角色随着音乐摇摆起舞。比例如以下图:
首先。你在打算移动游戏对象时。就要选取一个浮动的initialtime = Time.time,这样你的对象才干以正确的位置和方向開始,而且不会突然跳入动作。
下一步,我们就要想想三角函数的概念。
我们使用简谐运动,其形式例如以下:
Y是指当前值,A是振幅,f是频率,t是执行时间,phi是指阶段。首先,我们非常easy确定振幅。它是我们希望对象所具有的最大化高度或旋转。
下一个就是执行时间和阶段。
我们将用(Time.time-initialtime)轻松代替t而一次性处搞定这两者。
这会将φ降为0,所以最后我们仅仅须要得到频率。我强烈推荐令此频率与你的音乐频率吻合(假设你是自己作曲。这一点非常easy办到)。
假设你还不知道自己音乐的BPM,那就去摸索每一个节拍,直到弄懂为止。假设你已经有节奏感,这就非常好办了。假设你没有,那也不用操心。我们会利用中心极限定理。
持续点触你的整首歌。每欠点触都会降低平均值中的错误。
如今你就知道它每分钟怎样打节拍了。
你将以60来划分这个值,找到每秒多少拍。假设你仅仅想在半小节或一个完整的小节中使用一次动作,那就能够按2或4数值来划分。这个数值就是频率。你能够从 Mathf.PI获得pi。所以如今你要将对象的位置设为该数值。
此时你仅仅是在调整高度:
transform.position = new Vector3(transform.position.x,maxheight*
Mathf.Sin(2*Mathf.PI*frequency*(Time.time-initialtime)),transform.position.z);
但这还不够好。首先。我们要让对象合拍,这样它就得从其最大振幅開始。我们此时要使用余弦。但更重要的是,要让它从一端跳跃到还有一端,这样它就不会像波纹一样滑上滑下。这时要用cos^2,这样它才会突然停在0标记,并再次走向正数。因此:
transform.position = new Vector3(transform.position.x,maxheight*Mathf.Pow(Mathf.Cos(
2*Mathf.PI*frequency*(Time.time-initialtime)),2),transform.position.z)
这里要注意舞动的高度。终于旋转要使用正弦,这样其旋转和转化就是异相的。因此:
transform.rotation = Quaternion.EulerAngles(0, maxRotation*
Mathf.Cos(2*Mathf.PI*frequency*Mathf.Sin(Time.time-initialtime)), 0);
这里要记住两件事:假设你使用一个位面。并希望它面对摄像机,这些值就不能是0和0,而必须是pi/2和–pi/2。这里我使用的是EulerAngles而不是Euler,由于Euler使用的是度数,而EulerAngles使用的是弧度。
我们要做一些数学运算。我们如今要运用弧度,所以得使用EulerAngles!否则你之扣就得输入一个换算因数。
在此你能够看到我新游戏的一种类似动画,你能够用同种方法更改比例而不是位置。
如今我们要讨论最后一种动画类型:
纹理补偿
你能够用自己所学到的一切来操作2D纹理补偿。以制作美妙的动画背景。你能够在《Rude Bear Radio》及其主界面中看到我对《VVVVVV》的拙劣模仿。抓取一个位面,在其上粘附一个反复纹理,编写一个FixedUpdate() 函数。并依据下属性进行调整:
renderer.material.mainTextureOffset
renderer.material.color
这将导致墙体四处滑动并改变颜色。
最后。假设你想让它们看起来更有趣,还能够运用renderer.material.mainTextureScale。
这能够制作一个真正有趣的视觉效果,但它非常有干扰性,不要让它影响你的主要游戏玩法。
最后,你还得看一下当中的插值。
这能够让动画制作更轻松,但我个人觉得在第二部分中最好使用公式。
分享2D Unity游戏的动画制作经验的更多相关文章
- unity中的动画制作方法
Unity中的动画制作方法 1.DOTween DoTween在5.0版本中已经用到了,到官网下载好插件之后,然后通过在项目中导入头using DG.Tweening;即可. 一些常用的API函数 D ...
- Unity游戏开发--30s制作精美地图
"君子生非异也.善假于物也"--<劝学>荀子 引用这句话的目的,是我觉得有时候.利用工具来提高游戏开发效率是很必要的. 利用工具,解放程序员双手. 今天想给大家介绍下. ...
- Spine应用--使用Spine动画制作动作游戏
在前面的文章中,已经陆陆续续的讲解了一些使用Spine动画的细节,有了这些细节,我们已经满足了在unity中使用Spine动画制作动作游戏的技术基础. 那么,要使用Spine动画在unity中制作一款 ...
- 自制Unity小游戏TankHero-2D(1)制作主角坦克
自制Unity小游戏TankHero-2D(1)制作主角坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...
- 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇01:播放序列动画》
1.播放序列动画 系列动画播放概述 2D游戏中的动画系统,不同于3D游戏.3D游戏中,角色美术资源不仅包含角色模型的,还包括角色的贴图和动作等,模型本身自带角色的动作动画效果.2D游戏中,角色美术资源 ...
- 手游[追忆之青]动画导演:2D动画制作技巧
转自:http://www.gamelook.com.cn/2016/09/264591 GameLook报道/由一般法人计算机娱乐协会(CESA)主办的CEDEC2016日前在日本横滨举行,诸多开发 ...
- 自制Unity小游戏TankHero-2D(2)制作敌方坦克
自制Unity小游戏TankHero-2D(2)制作敌方坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...
- Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机
Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现的 ...
- 纯干货!live2d动画制作简述以及踩坑
本文来自网易云社区,转载务必请注明出处. 1. 概述 live2d是由日本Cybernoids公司开发,通过扭曲像素位置营造伪3d空间感的二维动画软件.官网下载安装包直接安装可以得到两种软件,分别是C ...
随机推荐
- SDWebImage 清除缓存
1.找到SDImageCache类 2.添加如下方法: - (float)checkTmpSize { float totalSize = 0; NSDirectoryEnumerator *file ...
- PHP获得文件的md5并检验是否被修改
由于需要判断上传的文件是否被修改过,需要记录上传文件的md5值,所以这里说一下一下获取文件md5值的方法. md5_file() md5_file() 函数计算文件的 MD5 散列.md5() 函 ...
- jQuery预加载插件
插件描述:jQuery Fadeloader的插件可以让你轻松实现预加载到您的网站或部分使用级联渐显效果来显示特定的内容块(例如,头> MENU>内容>页脚) jQuery Fa ...
- BZOJ 1592: [Usaco2008 Feb]Making the Grade 路面修整
Description FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中. 整条路被分成了 ...
- 【POJ 2152】 Fire (树形DP)
Fire Description Country Z has N cities, which are numbered from 1 to N. Cities are connected by h ...
- [topcoder]KingdomReorganization
http://community.topcoder.com/stat?c=problem_statement&pm=11282&rd=14724 这道题是最小生成树,但怎么转化是关键. ...
- 关于PowerBuilder 9.0中如何修改项目工程名字
关于PowerBuilder 9.0中如何修改项目工程名字,首先要找到三个文件,xxx.pbl.xxx.pbt.xxx.pbw这三个文件,为何要找这个三号个文件呢? 因为在使用PowerBuilder ...
- 33个优秀的HTML5应用演示 (转)
33个优秀的HTML5应用演示 (转) HTML5能做什么?取代Flash?制作动画?开发程序应用?这些都只是HTML5的一小部分功能而已. 大家可能听到很多关于Flash是否会被HTML5取代的讨论 ...
- MySQL优化器join顺序
前一篇介绍了cost的计算方法,下面测试一下两表关联的查询: 测试用例 CREATE TABLE `xpchild` ( `id` int(11) NOT NULL, `name` varchar(1 ...
- UVA_11178_Morley's_Theorem_(计算几何基础)
描述 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=23&pag ...