三消类游戏一直是游戏市场上经久不衰的休闲游戏类型,该类型也是源自于经典的俄罗斯方块玩法的一部分。三消游戏需要交换游戏中相邻的两个方格,以让3个或更多相同的方格连成直线,一旦连线成功,则消除这些连成线的同色方格,并使用新的方格进行填充,填充后如果还能继续消除就可以达成Combo或多倍加分!
本教程就为大家分享如何在Unity中制作这样一款三消游戏的完整过程,从创建底板填充方格开始,到统计步数并计算游戏得分,来自己做一款三消游戏。
准备工作
将项目初始资源导入Unity项目,资源目录如下:
其中分别包含要用于游戏的动画、音效、字体、预制件、场景、脚本及图片资源。
创建游戏底板
打开Game场景,新建空游戏对象命名为BoardManager,该对象将用于生成游戏底板,并填充方格。然后将Scripts/Board and Grid文件夹下的BoardManager脚本拖拽至刚刚创建的BoardManager游戏对象上:
BoardManager脚本代码如下:
BoardManager脚本声明了一个单例名为instance,便于其它脚本访问该脚本。
characters是方格需要用到的图片列表。
tile是用于初始化方格底板的预制件。
xSize及ySize是底板横向及纵向的数量。
tiles是保存底板方格的二维数组。
IsShifting函数用于检测是否需要填充方格。
Start函数用于初始化BoardManager脚本实例。
CreateBoard函数用于创建底板,参数为方初始化格图片的宽度及高度,根据此前定义的底板方格数量及底板方格预制件,来初始化整个底板。
在层级视图中选中BoardManager对象,然后在检视视图中将BoardManager脚本的Characters元素数量设为7,然后将Sprites/Characters文件夹下的图片绑定到数组元素。最后将Prefabs文件夹下的Tile预制件绑定到脚本的Tile字段,将BoardManager脚本的X Size与Y Size分别设为8、12。完成后如下图:
然后运行场景,可以看到底板能够正常创建,但出现了偏移:
这是因为底板方格从左下角开始最先生成,而首个方格坐标为BoardManager对象坐标。下面调整BoardManager对象的坐标为(-2.66, -3.83, 0),让BoardManager坐标位于屏幕左下角。
随机生成底板
打开BoardManager脚本,在CreateBoard方法中新增以下代码:
以上代码的作用是将所有底板方格的父对象均设置为BoardManager,保持层级视图干净整洁,并从之前定义的数组中随机选取一张图片来初始化方格。现在运行游戏,效果如下:
上面生成的方格还有些小问题,就是一开始就出现了连续的可消除方格,下面就来解决这个问题。
避免初始化重复方格
底板方格按从下到上从左到右的顺序创建,所以在创建新方格前要对相邻的方格进行判断。
上图所示的循环会从左下方开始遍历方格,每次迭代都会获取当前方格左侧及下方的方格,然后通过随机选取这两个方格,来保证不会在初始化底板时出现3个及以上相连的同一方格。更改CreateBoard方法代码为如下:
运行游戏,不会出现重复相连的3个方格了:
交换方格
下面来实现选中并交换相邻的方格。打开Tile脚本,其中Select方法用于选中方格后替换方格图片并播放选中音效,Deselect方法用于恢复选中方格的图片,并提示当前未选中任意方格。SwapSprite方法用于交换两个相邻方格,即替换两个Sprite的纹理,然后播放交换音效。这里通过按下鼠标左键来操作方格,代码如下:
这里还需要保证仅相邻的方格才能进行交换,在Tile脚本中添加以下两个方法:
其中GetAdjacent方法用于检测某个固定方向是否存在方格,如果有,则返回此方格。GetAllAdjacentTiles方法则调用GetAdjacent来生成围绕当前方格的列表,该循环将遍历各个方向与当前方格相邻的方格,并返回列表,以保证方格仅能与其相邻方格进行交换。
保存代码后运行场景,效果如下:
检测相同方格进行消除
消除可以拆解为几个步骤,首先判断是否出现3个及以上相连的同样方格,如果有,则消除已匹配的方格,并填充新方格。然后重复此步骤直至没有有效匹配。
在Tile脚本中新增以下代码:
FindMatch方法接收一个Vector2参数,用于表示所有射线投射的方向,新建GameObject列表来保存所有匹配条件的方格,从方格朝参数方向投射射线,直至射线未碰撞到任何方格或与当前方格不一致时停止,然后返回匹配条件的Sprite列表。
ClearMatch方法会按照给定路径寻找相同的方格,并相应消除所有匹配的方格。即判断FindMatch方法返回的列表中,是否有相连为直线的3个及以上相同方格。如果有,则将matchFound设为True。ClearAllMatch方法会在找到满足条件的匹配后,删除所有匹配的方格。
运行游戏,效果如下:
填充空白方格
在消除方格后,还需要为其填充新的方格。在BoardManager脚本中加入以下代码:
其中FindNullTiles方法用于查找是否存在空的方格,如果有,则调用ShiftTilesDown方法将周围的方格填充进来,该方法有三个参数,分别是X索引,Y索引以及延迟时间,X、Y决定了哪一块方格需要移动,这里仅实现向下填充,所以X值是固定了,仅Y值会变。GetNewSprite方法将生成新的方块来填满整个底板。
连击
新填充的方格可能会再次出现符合条件的匹配,所以新填充底板后要再次进行判断。再找到匹配后再次匹配成功,就是一次连击。所以在上面的FindNullTiles方法中,通过以下代码循环判断是否出现匹配:
现在运行游戏,效果如下:
添加计步器与分数
下面实现玩家步数记录,并统计游戏分数。打开Scripts/Managers文件夹下的GUIManager脚本,该脚本用于管理游戏UI,显示步数及分数文本。脚本代码如下:
在Awake中获取脚本引用,并初始化步数。Score及MoveCounter函数用于在每次更新分数值或步数时,UI界面上的文本也会同时更新。当步数减少至0时,游戏结束。此时会通过WaitForShifting协程在等待0.25秒后调用GameOver方法,并在GameOver方法中显示游戏结束面板。这里的等待是为了确保所有连击都被计算在总分内。
总结
到这里本篇教程就结束了,当然大家还可以在理解游戏机制后添加更多的玩法,包括限时结算模式、增加不同关卡与底板类型、连击的积分计算规则,或是为消除方格添加一些酷炫的粒子效果等等。后面就留给大家自行扩展与发挥了!
更多Unity相关技术文章
Unity 5导入Blender资源完整指南
Unity中如何使用Raymarching实现惊艳的图形效果
进阶Unity开发不能错过的Unity完整游戏教学案例
Unity 5 教程 | 低多边形场景的光照与后处理
使用Unity在HoloLens中实现《终结者》视觉HUD