自制简易星露谷物语(Unity)

1.人物的创建

先将素材拖入Unity当中

而后将Sprite Mode改为Multiple方便修改,而后将Pixels Per Unit改为16(因为作者设置素材时就是使用它和Unity中的比例大概为1:16)

之后点击Sprite Editor修改为如此,这样子就会使其贴着小人进行剪切,当然也可以如下图二改为自己修改。

之后将Fileter Mode改为Point (不利用差值,因为已经是像素画了)以及 Compression改为none(不压缩画质)。

将摄像机缩小

然后把小人拖入Scene中

2.人物的移动

创建一个脚本命名为player拖入上节课拖入到Scene中的小人身上

脚本这么写 已经在之前提到过 这是利用Tranform直接修改位置 当然也可以利用刚体组件

那么就是是否要将Speed改为public,如果你是想私有但是在Unity中也可以修改的话 需要在上面添加一行    [SerializeField] (表序列化)。

接下来需要为其添加移动的动画 先创建一个放动画的文件夹Animations

顺便提一嘴如果你不喜欢这样的命名

可以点到素材里一个一个进行修改 在右下角Name那里

选中前八个 拖入在Scence中的小人

以此类推 八个八个的拖到小人身上 最终如下图创建四个

当然还有一个办法 因为我们发现左右动作其实都是对称的,其实可以利用翻转便可以 如下图 便可以实现向右走

但是现在会发现小人一直都是向下走的动画,所以我们需要在动画管理器中修改一下

建立一个空的动画 把它设置为默认

而后将四个动画先删除掉 并创建动画混合树 这样子可以通过参数去调整动画

点击进入混合树改为2D Simple Directional 这样子可以通过两个参数改变动画

添加四个方向

将四个动画拖入 并点击画面中间的➕添加两个变量

注意右边变量改为 x和y 而后把pos x以及 pos y改为对应的方向

将空动画和移动动画连接 因为可以互相转化 所以都需要镜头 并且添加一个bool类型的变量 IsWalk

之后点击箭头 设置Hit->Walk为Ture 相反为Fals 并且把Has Exit time 取消勾选 (它的意思是是否要等动画播放结束了再修改状态,当然不需要,因为我们要随时从Walk到Hit Hit到Walk)

Trans Durtion设置为0 要不然转换的时间都超过了你按下键盘的间隔

添加脚本

获取Animator组件

并且设置变量

写完之后会发现小人在随着移动之后 仍然会在最后回到指向前面 而不是停止在面向的方向,所以我们需要在写四个动画。

并且在Animator中添加一个新的混合树 按照上面说过的大差不差的设置

最后将它设置为默认状态,并且与Walk用箭头相互连接。把右边的条件从上面复刻下来,便可实现。

3.瓦片画板的设计

一共有三种方法

刚开始都是创建一个新画板

第一种方法就是直接将素材拖入其中

但是我们如此考虑的话会发现如果是要做边境和内部 会发现需要来回切换 所以很麻烦 就可以使用RuleTile

但是我们发现创建一个RuleTIle的话得点很多东西 所以又使用了一个OverRuleTile 就只需要拖入就好了

点击Sorting Player

建立这几个图层

先复制四个图层将其修改成对应名字

然后在Bottom填充悬崖 使其出现高度

接下来点击Top层级先对其添加与土地连接处,可是你会发现基本找不到十分吻合的,这时候我们可以考虑修改TransForm的x坐标 进行平移(记住是top层级的)

做出这样的效果

4.房子的碰撞和一些不可到达的区域和相机跟随主角和相机边界

房子碰撞

先按照上面的方法将素材切割等做完之后 拖入素材 记得把素材的材质放在Game层

然后设置房子的中心点在下方

菜单栏Edit -> Project Settings -> Graphics -> Camera Settings:

为房子添加Box collider组件 并设置在范围在屋子的下面

按照同样的做法为小人创建Box collider2D也设置在脚下 并且添加Rigidbody2D 并且开始z轴锁定

不可到达区域

添加Tilemap Collider2D 如果碰撞的话直接在那个瓦片变成Collider Type->none 下图二

相机边界

先下载一个插件 

使其跟随Player 并且点击select

添加之后 在创建一个新物体 添加Polygon collider2D脚本设置边数以及大小最后拖拽到select里设置的那个脚本。

如果现在开始游戏 会发现小人会被挤出去 所以我们要给这个新建的游戏物体添加一个图层 并且把这个图层与图层碰撞都取消掉。菜单栏Edit -> Project Settings -> Physics 2D:都取消勾选。

5.拾取

先将素材导入 也是和上面的步骤一样先切割然后设置无差值已经不要压缩画质

注意这里用32导入后会比较合适

把种子作为预制件 并为其添加标签 和Box collider碰撞检测 记得把Istigger勾选 因为只做检测(这样子就不会模仿物理效果)

之后为Player添加脚本

意思是碰到那个便签内的物体 物体会消失。

6.存储数据相关的类

ItemData是用来存储物品的相关信息 SoltData是我们存储了几个 InventoryData的意思是仓库  一共有两个仓库 一个是物品栏一个是背包。

而后在脚本文件夹中再创建一个Data专门存放数据类的脚本

创建一个ItemData脚本

记住标出来的地方和下面继承的地方 这样子就可以创建数据对象

再写出两个脚本一个是保存目前的我们拥有的物品 之所以要加上可视化 是因为下图二那个背包是用SoltData类的集合 所以如果SoltData不用可视化的话 就不会在Unity中显示出了。

这一个作为物品栏 之所以也要CreatAssetMenu是因为我们下次进去数据也可以保存

演示:先创建一个Resources的文件夹 里面创建Data文件夹 下次可以直接加载这个文件里的数据 就可以回到上次保存的数据的游戏状态。

那怎么做到加载呢 就又得写脚本 首先创建一个空的游戏物体为他添加脚本InventorManger

之后打开脚本 先使用单例模式  之后创建Dictionary的集合 里面放的是ItemType 和 ItemData 之后创建Init方法用来得到Resources里面的Data文件夹的数据 他会返回ItemData类型的数组 将其接收之后放入DicTionary的集合里

之后再用GetItemData方法进行读取 尝试读取Dictionary里的集合是否有这个Type类型的 如果有return回去这个类型的data.

7.添加物品的功能

首先InvantorManger里添加一个InvantorData类型的变量backpack;

将其加载 并且记得把Init放到Awake里

一共有两种情况 一种是已经存在且没超过最大存储量时 数量加一便可

另外一种是之前不存在要存入就得把这个Item加载到里面

为拾取物体添加脚本 并且在Unity中选择他们的类型

修改一下Player碰撞检测的脚本 这个时候就运用了单例模式

之后进行检查 游戏开始前没有

背包也为空

游戏开始后 自动加载到这里面

吃种子后

8.UI界面

背包UI

先导入素材 之后也是设置和之前一样

添加一个Image

记得把画布的这个调整一下 要不然图片放入时大小不一样

之后把Image删除 然后创建一个容器 可以把容器的Image删除了

在这个容器下面添加Image(三个)

然后分别添加 这三个图片

之后选中这三个Image创建一个GameObject Empty作为他们三个的父物体 然后France的需要按住alt键选择左下角的 其他两个不用按住rh

然后缩放到合适的大小

在创建一个游戏物体 添加Grid Layout Group脚本

Spacing 设置为20 这个是间隙

Cell size设置为90*90 意思差不多是一行能让你放几个

然后在这个游戏物体下添加子物体Image类型的

然后将其放入图片 复制粘贴

可以参考一下啊

然后就是在预制体的文件夹里创建一个UI预制体文件夹 然后把格子放入 如下

之后创建一个Image在这个预制体的子物体下 然后顺便创建一个Text Mesh 记得把Auto Size勾上 而后下面的那个文字格式也换成位于右下角

接下来我们就要添加背包UI的显示和隐藏

先在创建一个Image 修改名字为Close——Button 添加图片 并为其添加Button组件

创建一个UI脚本

为其添加BackpackUI脚本

然后拖到Backpack

之后按照下图这么写你会发现 关闭了就没办法打开 是因为点击Tab会禁用这一个游戏物体 导致脚本也被禁用了所以再次点击Tab就没有反应了 (里面Tab写错了 在后面都改回来了)

所以需要 先选中这些UI在创建一个父游戏对象 叫做ParentUI 同时它是BackpackUI的子物体

接下来需要继续改进 因为点击叉叉也需要关闭

在Button里添加方法

接下来就是对其更新

首先我们需要把Back设置为24个 因为要和背包一一对应

接下来我们就得考虑 因为每次打开可能顺序会发生变化 所以我们需要好好为其添加一个SoltUI脚本 并标记好记号

 接下来我们需要实现物品在UI界面的实现

首先我们需要创建一个LIst集合用来接收InventorManger的backpack 而backpack来自我们存储的数据里 之后我们就需要创建一个新方法更新里面的图标 上面的InitUI我也修改了一下代码 因为我发现有空指针。

然后在SoltUI里添加新的方法 是为了发现Back那个数据(下图二)里是否有数据 如果没数据的话就不要显示  那两Image和TextMeshProUGUI类型的变量也是新创建的。需要在Unity里拖入一下。 记得预制件也需要。

接下来我们就要实现捡到物品更新

定义一个监听事件 其实它的意思Action会变成那个类 所以就可以使用那个类的任何一个函数方法

之后就是写一个方法用来接收这个监听的事件

然后在SoltUI里传递一下OnDataChange这个方法

然后就是如果有更改数据的话添加上使用这个方法

就可以实现更新

工具栏UI

先导入素材后 还是一样的步骤让他更清晰等等等

而后创建一个UI->Panel 把Image删除 然后在创建一个子物体ParentUI 放在正下方 并且把Stretch调整到最下方。然后在ParenntUI再创建一个子物体UI->Image 里面拖入我们的物品栏。

接下来在创建一个空的游戏物体叫做ComtestLIst 在ParentUI下面

添加一下脚本HorIzontal Layout Group

在这下面添加复制一下游戏物体 如下图

然后把下图都勾选上

调成下图 记得把ComtestList的中心放在中间这样子才会显示在Center

接下来就是调整 也就是把Spacing调整到合适

Spacing是调整里面的间隔

0时

13.75时

接下来就得做工具栏的特殊设计

首先我们发现换成Dark就可以表示被选中 状态 那么接下来我们需要考虑的就是添加数字 现在SoltUI下面再添加一个Image 将其背景设置为黑色透明点的颜色之后再添加一个Text——meshpro

调整它的Autosize勾选后 在调整大小和Image一样大 之后调整min使其只出现在Image范围里 记得把Strech改为与父物体保持大小

而后添加一个脚本ToolBarSoltUI 继承SoltUI

将背包栏的物体设置新的脚本到身上 并且改为一个新的预制体 并全部更换

然后也是设置Index从1-8 拖入图片 修改Image下面的TextMeshpro的序号等

接下来我们要做更新背包的效果

因为只要换成高亮就是选择状态 所以如下图就好了

接下来我们需要创建一个与背包一样存储数据的对象 大小为9个

接下来我们需要在InventorManger里一样的加载数据进去

然后接下来我们需要在创建一个ToolBarUI的脚本 

因为和BackPackUI差不多 所以我们需要InitUI和UpdateUI这两个方法复制过来 修改一下里面的数据类型就ok这样我们就做好了数据的载入

之后Updata里面就是做选中处理 因为从一到九都写个if太麻烦了 所以我们发现KeyCode.Alpha1 - KeyCode.Alpha9是连续的 所以我们只需要让他for循环一下 看输入的是哪个 这个时候就会衍生出另外一个问题 上次按完1之后1已经变为高亮 那么现在再按2 1应该取消高亮 所以我们设置了一个变量 用来记住上次选择的高亮 然后到时候取消就ok 然后i不是等于(int)KeyCode.Alpha i 那么减去(int)KeyCode.Alpha1 的话正好数数组的大小 便可以完成选择操作。

拖拽事件的的学习

先创建一个游戏物体 使其包含两个Image 在Image上添加一个脚本Event Trigger这个是用来包装事件的

接下来我们会发现 一共有四种拖拽事件Begin Drag    Drag     End Drag    Drop

我们在游戏物体上添加游戏脚本

然后拖入各个的事件中

然后我们开始执行游戏

于是得出结论Begin 只会在拖拽时执行一次 End只会在松开时执行一次 然后Drag是没松开时一直会执行 然后Drop是小黑这个物体拖到小红时松开 然后会在小红身上执行。

但是这其实是对移动端来说这么设计

对于电脑端有个更合适的方式 利用鼠标点击进行交互

所以我们要创建一个新的游戏物体作为游戏拖动 并为其添加一个新的脚本ItemMoveHider

检测鼠标的点击有两种方式 一种是利用脚本 另外一种是利用接口

那么利用脚本的方法就是调用EventTrigger 里面就有个PointClick 

利用接口的方法就是导入一个接口

之后在每次点击之后都会触发

那么之所以是要在SoltUI里添加是因为我们要知道我们点击的是谁

要把这个传到ItemMoveHider脚本里

接下来我们需要做的就是物品跟着鼠标移动

先在SoltUI里添加一个方法得到SoltData

现在就可以把SoltData传过去我们就知道了

就可以调用SoltData类的图片 之后再脚本里设置一个隐藏和显示的方法 当SoltUI的点击方法触发的时候 触发Show()

记得把这个取消勾选了 因为如果勾选了图片就会把鼠标发出的射线给全部接收了

我们现在已经可以做到点击UI时会触发相应的事件

但是扔东西的话 肯定是扔到地上 而地上又是非UI的 这要怎么办呢

我们就需要 这段话的意思是如果点击的不是UI的话

然后因为我们要扔在Player的周围 所以要在Player的脚本里写个方法

那么我们就要在ItemMoveHide里调用这个方法

首先我们需要得到Player类 顺便说一下添加一个这个Hide()在Awake里使用 为了让他刚开始时鼠标上没东西

然后补充一点记得要在点击的方法中把SoltUI赋值一下

之后就是写下这个代码做到调用Player里面的ThrowItem方法 并且仍一次手里就没东西了

接下来我们需要做到物品的更新

我们需要在Soltdata里再添加一个清空的脚本 因为我们现在只是做到了一次全部都扔掉

然后在这里调用

接下来我们就要实现按下CTRL键 实现一个一个扔

先写一个变量 当按下Ctrl时为true 松开为false

接下来我们需要在在SoltData里再写一个数字一个一个减少的方法

这个的意思是如果正好减到0的话其实就是清空 然后都得调用更新UI的方法

之后开始写判断条件进行调用

但是我们会发现一件事情

如果这个时候扔完了 但是你的鼠标上面还会跟着一个图片 所以为了防止 我们需要在最后判断一下是否为空 如果为空的话 使用Clear方法。

接下来我们需要做物体移动到空格子上的操作 但是我们得先完成一部分的修改 新添加一个变量selectedSoltData 并且把selectedSoltUi禁用掉

这里面的改成这样 这样子就可以少一层调用

然后就可以把出现SelectSoltUI的全部换成这一个selectSoltData 

那么我们就要开始设想 是不是鼠标上得有东西才可以进行其他操作 所以先if else判断鼠标上是否为空 如果为空的话赋值一下

那么现在如果不为空了 就得判断一下我们现在点的是不是空格子 如果是空格子的比较简单 就是移动 我们可以先做一下 写一个方法 对应从哪一个换到哪一个格子 (fromsoltData->tosoltData)那么我们接下来就得再写一个移动的方法

这个方法的意思是是如果按下Ctrl的话就是from-,to+。 如果没按下的话就是from全部移动到to 所以在最后可以判断一下 from是否已经全部没了 如果没的话调用一下clear。

接下来我们需要的就是取消脱移的功能 点击鼠标右键时直接出发Clear()就好了

接下来我们需要完成往不是空的格子里移动 又分为三种情况

点击到了自身 那么不做任何处理

点击到了不是自身 但是是同类型 做加处理

所以我们需要在创建一个方法MoveItemNotEmptySolt()

首先是按下Ctrl的话那就是from-,to+ 不过得判断是否还可以添加进去

如果没有按下Ctr的话就是整体移动 就得判断是否装得下

所以我们需要在SoltData里面再添加一个函数 用来得到剩余空间

顺便修改一下增加和减少的方法 把它改为默认+1或者-1 但是也可以自己传参

做完了这些工作后我们就可以继续移动 如果整体移过去 装的下的话 就直接to+from的数目 然后把from清空一下 如果装不下就只能装得到的空闲空间 然后from的数目得减去空闲空间的数目 最后判断一下selectdatasolt还有没有 如果没有的话就clear清空掉鼠标上的图标

还有另外一种情况就是点击到不同类型的物品 就要触发交换功能

所以添加一个新方法

这个方法主要是得做到交换 就先再用一个变量保存一下data1 然后直接把data2移动到data1

之后把变量的数据赋值到data2 我们前面都是如果原本图标里的数目为0了再清空鼠标上的图片 但是到这里因为就是交换 所以直接调用clear就好

可以去改一下Soltdata里的 新添加一个物品的功能的方法 改为默认count为1 但是也可以自己传值

这样子 变量的数据赋值到data2时 就可以直接传值 比较方便

9.锄头的制作

先将图片导入后 仍然是调整那几个设置 然后选择任意一个命名为Hoe

按照下图添加碰撞体 和 刚体 和pickable脚本 碰撞体勾选isTrigger    Gravity Scale为0   Linear Drag = 0.1;并且把游戏图层设置到Game

把标签设置为Pickable

接下来我们就要实现选择了锄头之后按下空格可以播种 写在这里面

之后我们得用一个瓦片来辅助我们编译时进行可视化 所以导入一个瓦片 并且把他的名字改为Interactable_Editor然后修改图片透明度少一点

然后我们刚开始创建的Interactbale 因为肯定是土地才可以种 所以得把它的position和Buttom_Ground_Top一样 之后在Interactable上绘制可以耕种的区域

然后接下来我们需要考虑的是Interactable_Editor只是程序员我们自己看 所以在游戏运行时不可以看见 一共有两个方法

一个是把下图那个地板的透明度在游戏开始时设置为0 但是又有一个物体就是 那么锄地之后地的改变也会显示不出来 因为直接把这个地板设置为透明度0了

第二个方法就是把Interactable_Editor复制一个Interactable 把复制的图片透明度设置为0 在游戏开始运行时替换成Interactable

之后再创建一个PlantManger 设置为单例模式 接下来我们要做的事在游戏运行时把Interactable地板里的瓦片在游戏运行后把Interactable_Editor换成Interactable

之后就会发现点击游戏开始后 那块区域就被替换成为不可见的

接下来我们就要做到按下空格键并且选择锄头的时候 进行锄地

首先我们新建一个变量和方法 在变量里拖入锄完后的地 

然后我们就可以跑到那个按下空格才可以执行的地方进行方法的调用

先利用标签得到玩家所在的位置

之后传入便可

但是我们会发现 其实锄地的动作要想完成是在Player里 所以我们需要把这些代码迁移一下 首先将在SoltBarUI里面的代码段注销一下 添加一个获得被点击背包是哪个的方法

然后把注释掉的代码复制到Player里面 (在SoltBarUI里获得Player位置的变量也可以删除了)

创建一个ToolBarUI 在Unity里拖进去 然后我们就可以在Player里面获得被点击的背包是哪一个

接下来我们就可以最后做一步 锄头动画的制作

先把动画拖入到Player 然后创建一个动画管理树

接下来我们就得知道Hoe是不需要来回实现的 所以只需要一个触发器触发一下就好了 所以新添加一个变量Trigger类型的Hoe

因为在任意状态静止的任意状态都可以锄地 所以把Has Exit Time取消勾选 Trans Duration改为0

然后为这个箭头添加触发器Hoe 

然后Hoe返回站立状态只需要 一执行完返回便可 所以不用动什么

最后在Player的脚本里添加一下执行语句便可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值