Unity游戏开发范例之从零开始的种田生活

(本文难度★☆☆☆☆,作者 @酒九大魔王 )
大家好,这里是暴躁老哥酒九。
最近,我们的童年记忆《摩尔庄园》在手机上面复活了,不知道大家有没有沉迷于种菜无法自拔呢(反正我是累了)。

在《摩尔庄园》中了为我们玩家提供了很多的玩法比如:钓鱼,烹饪,开餐厅,庄园和玩家自身装扮,职业选择和种田(小声逼逼:虽然我都觉得挺鸡肋的)。
想象一下,大家在现实中打(mo)完一天工(yu)以后,回到家还要坚持在游戏中种田,浇水——什么叫做热爱,这就是。
OK进入正片,我们首先想一想我们做的是一个种田的游戏。
那么问题来了,流程是怎样的呢?
首先玩家需要开垦一块土地,然后在背包栏中选择到对应的种子,再在被开垦好的土地上进行播种,然后就是等待种子生长好了以后收获果实,卖出获得金钱,再去商店买种子。
实现这个流程并不困难,重点在游戏中各项信息本地存储。这里将会罗列出我个人使用最多的三种Unity中信息存储方式。在此之前,我们先来进行制作。
首先找到需要的场景素材,无论是在Unity的官方商城还是某宝上购买都没问题。
将场景素材下载好了以后,打开Unity新创建一个工程取好工程名设置好工程的文件的保存路径,打开工程将下载好的素材包拖入工程中。搭建一个自己的场景,选择好人物模型,大家可以用自己的方法来控制人物的移动,这里就不过多描述了。

但是,想要到达上图的效果我还缺少了一步——摄像机的跟随。所以新建一个脚本命名为CameraFollow,在这个脚本中编写摄像机跟随的脚本。
将编写好的CameraFollow脚本拖到场景中的MainCamera上去再把人物拖到CameraFollow下的player中去。然后再场景中去调整摄像机和玩家的位置选择一个合适的距离和角度。再运行游戏就可以看到上图的那种效果了。而且再玩家角色被物体遮挡时(当前的遮挡物又碰撞体)摄像头会自动调整位置看向玩家。这里我就不放图演示了。
接下来就是上面提到的重点(敲黑板):
游戏中玩家能种植不同的种子,不同的种子拥有不同的名字、持有数量、描述、成长时间、在场景中显示的模型以及在UI界面显示的图片等等。怎么来实现具有这些信息的不同种子,通过创建包含这些信息不同的预制体?可以。且先不说一款通常的种田游戏中的道具种类和数量都是很多的,如果当游戏需要调整时,制作者就需要一个一个到预制体中去进行修改。这样的方式太麻烦也太笨拙了。这里就需要抬出上面所说的三种存储方式了。
这三种信息存储方式分别是ScriptableObject,TextAsset,Json。
接下来我会根据游戏开发的推进来一个一个的为大家介绍使用。
首先是将游戏中的物品的信息进行分类。
在咱们这个例子里,某个物品的名字,描述,价格,(种子)成长时间是一开始就设计好了的,且在游戏游玩中也不会去更改。
物品在场景中的模型,以及在UI界面上显示的图片,也可以通过对于模型或图片在工程中的存放路径来读取。
而一个物品的玩家持有的数量是会随着玩家消耗或购买增减的。
这样就把物品的信息粗略分成了两类——在游戏游玩过程中会变的和不会变的。换个专业点的说法就是静态数据和动态数据。这里我选择将前者使用表格获取,读取方法就是通过TextAsset。后者则用Json文件格式来进行读取和存储。
PS:这里为了方便物品的主要演示的是种子类(其实就是没有找到合适的素材)。
CSV中的静态数据读取
这里先新建一个Seeds脚本,在里面声明一个Seeds类(种子类)
我们先不看那三个方法,后面会一个一个的给大家讲到。现在来打开一个XLSX工作表,在表中编写种子的静态数据内容。

怎样让Unity从表格中获取到这些数据呢?当前这个文件的格式是xlsx——也就是表格,我们人看上去直观明了,但Unity不能直接处理。因此需要我们将这个文件另存为seed.csv的格式。
这里简单的介绍一下CSV格式的文件。通俗一点来讲就是使用逗号来分隔不同的数据内容的一种纯文本文件格式。将写好的表格另存为.csv格式后我们用记事本的方式打开。

这里还需要注意的就是这个文件的编码是不是UTF-8,如果不是的话需要将另存为一个文本文件让后将他的编码选择为UTF-8的选项就行了(否则的话拖进Unity后可能会出现无法读取中文的问题)。
现在在工程中新建一个Resources文件夹,在该文件夹下再新建一个SeedData的文件夹把转换好的seed文件拖进去。新建一个命名为GetCSVdata的脚本用于读取静态数据。主要方法如下:
这样上面种子类中的构造函数部分应该就好理解了,就是从GetCSVdata的字典中把静态数据拿过而已。
Json中的动态数据读取
接下来就是我们的动态数据的部分。
前面说了需要用到LitJson,在网上有很多途径都可以下载。下载好了以后了在工程的Assets中新建一个Plugin文件夹将下载好的.doll文件拖到里面去。然后编写需要读取的Json文件信息——在编写Json文件时需要特别注意格式。

但是在编写JsonManager脚本之前,我们先新建一个BagManager的脚本:
然后现在再来编写JsonManger脚本:
主要内容如下:
现在一个个包含完整数据的Seeds(种子)都放在了BagManager中的seedsList中去了。接下来要做的就是将这些种子在UI界面中显示出来。
准备好一个预制体,将需要显示的数据通过对应UI控件来显示出来。所以我们还得写一个BagSeeds的脚本控制预制体将这些数据一一显示出来。我们先看预制体的准备。

在这个预制体中seed是一个Image,Count,name,info都是Text,而instructions一个Plane。再来看我们的BagSeeds脚本。
主要的显示方法:
最后还需要一个UIManager脚本来负责将这些预制体实例化出来,将UIManger编辑好了以后了挂载一场景中的空物体上就好了。下面展示一下主要的方法:
这里需要大家自己用UI控件做好背包栏。文章中没有详细说明制作方法,大家可以自由发挥,不过提醒大家记得根据自己需求添加上Grid Layout Group组件或者Horizontal Layout Group组件。现在让我们来看看效果。

ScriptableObject的使用
上图左下角显示的金钱数量也会即时存储,在这个例子中的实现用的是ScriptableObject。这里我会给大家“抛个砖”,简单的介绍一下使用方法。
ScriptableObject是一个用于生成单独Asset的结构。同时,它也能被称为是Unity中用于处理序列化的结构。工程中的所有的Object都能够通过这个方法进行数据的序列化与反序列化,方便从中获取各项数据。因为ScriptableObject是Unity为我们提供的工具,所以在里面我们可以直接定义多种Unity支持的数据类型(比如:Vector3,Quaternion等)。
首先新建一个Money类,让这个类继承ScriptableObject基类。在这个类中编写好你需要的内容。这个时候注意要在类上面加上这样一段:
这里的意思是在Assets文件夹中点击鼠标右键以后,菜单栏中新加一个按钮选项,此选项的菜单名(menuName)是什么,点击后生成文件名(fileName)为什么的脚本。
按照自己的要求编写好以后了,按照上述步骤生成一个Money类。就作为玩家的金钱在UI上显示出来就好了。

现在背包部分已经像模像样了,接下来就是土地的部分实现,思路和背包其实是一样的。
我们要一个土地类(Land)用来存放土地的各项数据,一个土地管理脚本(FieldManager)负责把读取到的土地放进一个列表中去,一个土地的预制体(newField)用于根据数据在游戏中生成土地,一个挂载在土地预制体上的脚本(Field)负责将信息的记录和更新还有主要的种植过程的逻辑,别忘了编写好存有土地信息的json文件(land.json)和在JsonManager中添加上对土地数据的读写。
这里大家会发现为什么我把土地的位置单独封装了一个Location类而不是直接使用Vector3类型。为什么呢?是因为LitJson不支持Vector3。所以这里大家要注意一下。
将土地生成在指定的地点。
这里说明一下土地在几个状态之间的变化,在可开垦(canReclaim)状态时和在可种植(canPlant)状态下的MeshFileter中的Mesh是不同的。玩家种下种子后土地状态发生改变(growth_1,growth_2,growth_3,)会在土地的中心点上生成对应的种子模型,每一次完成一次成长时间会转到需要浇水的状态(needWater)并且再玩家进行浇水操作之后从新记录开始时间,最后就是成熟(mature)。根据这个流程完成脚本。
这里需要我事先将准备好的两种Mesh放在了newField脚本中的一个列表里。再根据土地状态的变化来进行获取。
这里的seedInLand就是当前种植再土地中的种子ID,根据当前种子的ID来获取到所有的预制体,用一个列表来存取使用他们。
好了,现在大家编写好了土地的相关内容了,接下来的商店部分和游戏里的时间管理都是基于前面一样的思路完成的。这里单独的提一下在时间管理脚本中大家可以使用协程来完成现实时间和游戏之间的关联这里我就举一个例子:
这里还是先声明一个时间类(GameTime),类中的内容大家可以自行设计。上图协程实现的就是游戏中的时间流逝是现实时间的两倍,并且通过计算上一次退出游戏时最后的时间和下一次打开游戏的当前时间来计算出中途经过的时间来计算我们种的菜是否成熟。
最后我们来看看我们的成果:



工程链接:https://pan.baidu.com/s/1iJa6KiHZ5mdh-sVytQdM-A
提取码: d3v4
欢迎加入游戏开发群欢乐搅基:1082025059
对游戏开发感兴趣的童鞋可戳这里进一步了解:http://www.levelpp.com/
B站:“皮皮关做游戏”