我真的是,想起一出是一出,终于也要对Unity下手了。前几天看到油管上有一个up主,挑战12小时做一款游戏,既然看到了就很想挑战一下,看看我和大佬的差距,也是保持每天编程的手感。
游戏下载传送门
大佬的12h即是从早到晚连续的12h,包括吃饭。我是绝对做不到了,毕竟我也不是大佬,而且每天也有其他的事情要做,于是采用离散计时法,随做随计。
4h59m:
把player controller这一大块完成了,包括slow motion,ball squeeze和tail这些花里胡哨的东西也还原了。球的运动使用addForce()来做,Slow motion通过改变timeScale实现,球的变形通过改变gameObject的scale,tail一开始想得复杂,后来发现unity自带就有tail renderer。然后用slider去实现了aim line。其实也不算复杂,比较麻烦的就是各种数字的设置,力和速度的大小,重力和阻力什么的。
这里有一个bug尚未解决,就是addForce之后,球的运动有时候会产生偏移,即便是关掉阻力和重力也是如此,尚不清楚原因。
然后做相机追踪,包括移动缓冲和自动缩放。此时就遇到了第一个大问题。
相机跟随时物体抖动,速度越快抖动越剧烈,查了很多方法,也看了Update、FixedUpdate、LateUpdate各种关系依然无解,终究还是在国外某不知名论坛看到了解决方法。(百度不给力啊,还是谷歌靠谱)解决办法是把rigidbody里的interpolation打开,插值之后就能够纵享丝滑。不过关于Update这方面还有很多值得深挖的内容,以后得好好学一下。
5h48m:
制作敌人的碰撞检测,又遇到了个问题。碰撞之后丝毫无反应,debug发现连碰撞函数都没有进去,但是程序也没给我报错呀。
后来发现,我做的是2D游戏,设了Collider2D,在程序里就不能只写Collider,不然啥反应都没有还不会报错的。妈耶。
6h50m:
particle system做击中效果, 最烦人的一个部分,美工从来不是我的强项,没办法一个一个参数去试效果。
击中敌人爆炸,击中后先让sprite和collider消失,等particle system播完了再销毁对象。Like:
1 | void OnCollisionEnter2D(Collision2D other) |
7h24m:
post processing stack,看起来很厉害的东西,实际也很厉害,但是用起来没有想象中那么难。简单地说就是类似于相机滤镜一样的东西,不管你原来的场景做得多粗糙简陋,把它加进去之后简直化腐朽为神奇。这一块倒是没花很多时间,因为只是随便加了个效果,实在要达到大佬那样的视效还得仔细地去调参数,先放一放吧。
7h53m:
health bar & player health,做UI也很是繁琐,索性直接用个slider就完事了,美中不足是血条为0时会有一点残余,是由于这一点位置是原来slider的handle占着的,删掉handle就露出来了,留着后面想办法吧。
8h44m:
enemies spawn,既然大佬说是直接google的,那我也就直接借鉴大佬的了,只是参数还得再慢慢调。
这条公式具体如下:
1 | float yPos = Mathf.Floor(Mathf.Abs(UnityEngine.Random.Range(0f,1f) - UnityEngine.Random.Range(0f,1f)) * (1 + 100 - (-2)) + (-2)); |
当然参数是我自己调得,公式的作用就是让敌人生成的位置尽量靠近底部。
公式确实很神奇而且有效,学到了。
9h22m:
玩家死亡游戏结束,说实话这里没想到什么好方法,试过各种方法都有一点不完美,姑且是先清空速度停止位移禁用script,后面看看能不能写成boardcast的形式。
9h49m:
完成计算分数UI,用public static int 来构造类变量使别的类可以调用。
11h34m:
做了game over界面,你问我为什么这里用了将近两个小时,说来可笑,做完game over菜单其实也就十几分钟,然后打算加上游戏重新开始功能,其实用LoadScene()一行代码就可以搞定了,但是做完运行的时候发现restart按钮点第一下游戏重新开始了但是Game over界面还在,点第二下才消失,于是花式改代码花式查资料查api,心态崩了.jpg。就在大脑停止工作的前一秒,想到在start()的时候给判断游戏结束的参数重新赋值而不是在LoadScene()的时候重新赋值,就可以了窝。那一瞬间的心情,想必是悲喜交加的。
但是,anyway,游戏总算是能做出个完整的样子,此时距离12h的期限只有不到半小时。
12h13m:
虽然一直以来都是音乐苦手,但是碰撞爆炸音效什么的也大概是搞定了。顺便学会了用数组去获得object下的同类资源这么一个操作。Like this:
1 | public AudioSource[] AudioClips = null; |
即便本科的时候玩过一阵子FL studio, BGM也是真的搞不来,由衷佩服全能的大佬。
至此,大佬花了6小时包括吃饭上厕所以及构思。而我只能勉勉强强踩着12h的期限做出个仅仅是称之为“能玩”而不能称之为“游戏”的半成品。而且做的时间也是断断续续的。要说达到了大佬一半的功力怕是在侮辱大佬。
再往下做,就是一些细枝末节的东西了,优化游戏体验,更需要细心的去做,虽然内容不多,但是难度可不小哦。
12h40m:
撞击时相机抖动,这个地方搞了大佬一个小时多,我却意外的顺利【摊手】。撞击时给相机位置加个随机数,撞击过后再回到原来的位置就成了。于是可以得到完整的相机代码包括跟随与缩放功能如下:
1 | void LateUpdate() |
13h20m:
加了两种新的enemy类型,绿色的碰到就必死,紫色的碰到就给player来一个AddForce带你乱飞。
14h18m:
让镜头之外的物体在一段时间后自动销毁,避免占用太多资源,用这两个函数来判断:
1 | private void OnBecameVisible() |
然后加入combo机制,说实话,combo这个一开始想错方向,绕了好久的弯路。
最后加上一个esc键退出功能,就这么完结了吧。实在是累了肝不动了,而且也是超时了很多,在功能上面只能说尽力去模仿原作吧,然而bgm实在是搞不来,用别人的音乐又怕什么版权纠纷,虽然我这也不算用于商业用途。至于后来他还实现了黑洞,这个有考虑过也有了一点思路,但是做起来要花点心思,最近开始要渐渐忙起来了,所以就先搁置一下吧。
虽然一开始确实是兴趣使然地去做这个游戏,但其实稍微想想的话,这个游戏的可扩展性很强,还能搞出更多新的花样,比如排名机制,比如闯关机制,再比如更多的敌人和联机模式。说起来,简单的图形更能让玩家和游戏开发者都专注于玩法上,很多优秀的游戏从来都不是单凭画面拿下市场的,甚至画面粗劣却拥有一大票拥趸者的游戏比比皆是,像elona,像和班尼特福迪一起攻克难关….
不管怎么说,12小时的游戏开发挑战就先在这里画个休止符吧,毕竟也是一天一天的闲暇时间凑出来的12小时,也是蛮累的 XD