前言
这次学校工作室的考核任务(是的还是考核)是复刻一款游戏,给出了三个游戏选择(饥荒/杀戮尖塔/元气骑士)不过我都没有玩过,于是想了想我决定做一个简陋版的明日方舟。之前在b站看到过大佬仅耗时48小时开发出明日方舟的战斗界面,感觉好像也不会很难吧……就去试了!
但是做了之后才发现其实是很有挑战性的一次任务。先上两张游戏界面的图(p1p2)!
制作思路
场景:
最开始我的想法包括了五个场景:两个关卡、选择干员的界面、看板界面和登录起始界面(包括一些本地化的内容,工作量挺大的)。后来由于时间不够了就砍成了登录起始界面和一个关卡。
干员:2D骨骼/Trail Renderer
选择什么干员来演示比较合适呢?方舟并没有公开模型,如果要获取对应的gif会比较麻烦,而自己画角色好像也很麻烦。
纠结了半天我决定画三个自己的原创角色,并使用2D骨骼动画制作了相关的站立、战斗的动画(对2D骨骼感兴趣的同学可以在b站上找Michael老师的系列教程参考学习)
在干员战斗的时候你会注意到一些秘制特效,这是用Unity自带的组件Trail Renderer做的。这个组件很强大,如果加上一点代码能得到非常酷的效果。
关卡:2.5D/正交相机+透视相机
关卡界面我是完全按照方舟游戏本体的某一关来搭建的。
我们知道舟游的地图是3D的,但是干员又是纸片人,这种不同维度的结合势必会带来一些问题。几番考虑我决定在2D场景中创建3D的地图(其实是某种意义上的2.5D),正好Unity默认的Cube长宽为1,完美契合了地图格子的对应位置,能够得到图3的效果:
因为想要得到近大远小的效果,所以渲染地图的相机必须是透视而不是正交的,但是这样会导致我方干员贴图在挪动到地图边缘的位置时出现扭曲的现象。为了解决这个问题,我额外引入了另一个正交像机专门用来渲染干员预制件,这样干员在拖拽实例化之后怎么看都像端端正正站立在地图上的。
不过这样也会导致另外一个问题,那就是在靠近边缘的地方干员和格子可能无法很好的对应上。我认为是能找到一个数学模型来对应的,但是有点麻烦…
后来在参考研究48h开发明日方舟的白斗七星大佬的作品时发现他只用了一个摄像机,但是这个摄像机的机位很巧妙,把近小远大的影响压到了最小。
具体实现
标题场景比较简单,就是几个UI元素调到还行的布局,在此不多做论述。
在上一期《用Unity简单实现合成大西瓜》一文中,我在代码结构的处理上非常糟糕,该封装的东西都没封装,导致整个代码结构特别复杂也特别乱。这次在这方面做了一些小小的努力,相对结构也还是能看的吧(笑~)
敌人相关
EnemyWaveController参(zhao)考(ban)了油管上Brackeys老师的教程,EnemyMove则使用了A* 算法。对于网格地图上的移动,除了A* 之外还有好几种其他的寻路算法,感兴趣可以上b站找Joe的视频参考学习。
为了减小开销(在频繁销毁生成的资源很多的时候,这点非常重要),敌人的生成和死亡使用了对象池。
Player相关
第一次写接口(IPlayer)竟然是用在玩家的攻击和特殊攻击上。因为考虑到每个我方干员都有这两种攻击形式和一些属性,就整了这么个,后来用起来也还挺方便的。
PlayerMgr里的玩家列表对“已上场的干员”、“还未上场的干员”、“攻击范围内的干员”都有着至关重要的作用。UI的玩家图像按钮就是依赖于这个列表。
玩家信息则存放的是该干员的部署费用、名字等元素。
UI相关
有很多按钮的OnClick事件和一些与数值有关的事件委托。
其中最复杂的地方莫过于拖拽实例化+放置玩家+设置朝向。我的思路大概是这样的:
点击玩家按钮列表,利用eventHandler的drag函数在鼠标的地方实例化出对应干员 à 拖的时候对应的地块颜色变成绿色(调整材质球的颜色) à 松开鼠标,如果在适合的位置就吸附到该格子中心 à 调整朝向,攻击范围也随之改变 à 放置完成
想法挺简单的,写起来有点复杂…相信有更快更简洁的实现方式
回顾思考
值得改进的地方有许多,比如从代码角度出发,我的代码还不够精简(尤其是拖拽放置的那个模块),还不够OOP(
此外,从可玩性的角度出发,如果地图和敌人能做到随机生成,那么游戏的可玩性和难度会大大提升的
最后,感谢阅读到这里的你!如果你对这个项目有什么意见和建议欢迎在评论区和我探讨
源码已上传GitHub:https://github.com/Guiny-Time/Arknights