【Unity】手把手入门2D游戏开发教程——小狐狸的冒险(上)

本文章参考了以下有关文献或内容:

Unity官方文档教程:Ruby'sAdventure:2D初学者

本篇为前半部分基础内容,包括:控制角色的移动、脚本组件开发、Tilemap使用与地形绘制、地形碰撞器、物理系统(碰撞器、刚体组件等)、角色的回血与掉血触发、预制体等。

接下来正式开始我们的创作旅程。先创建一个2D项目


资源包内包括了官方提供的免费的Ruby狐狸以及其他有关资源内容,用于在这个项目上进行实操使用。



可以拖动到场景内


新建脚本文件夹Scripts,在里面新增一个脚本RubyController


把脚本丢Ruby控件属性内,成为它的一个组件。


进入项目配置项里面


输入管理器里面,可以设置一些参数。这些参数也可以被用代码进行获取,例如水平和垂直参数。

双击前面的C#脚本代码打开,新增一些代码,如下图。用于操作主角移动,并且使用来实现平滑移动。

deltaTime解释,可以参考GPT说明:


2D的帧率默认是60FPS,可以通过启动时候修改帧率。正常情况下不需要更改。以下只是示例。


场景移动时候,可以预设步长,步长设置,在场景内工具栏,点开,有一个IncrementSnapping

把步长距离设为1


测试下效果,环境里面随便拖入一个进去,然后Ctrl+d复制一个,再Ctrl+鼠标拖动,可以看到自动移动1个单位(一个格子长度),自动对齐。


移除上面的测试,新增一个Tilemap


会自动创建一个Grid,Grid下面自动会有一个Tilemap

Grid可以用于将游戏对象均匀分布在网格内;Timemap是网格地图,由Tile(瓦片)组成

Assets下新建一个Tiles文件夹,然后在文件夹内新建一个Tile,重命名为FirstTile



选中Hierachy的Tilemap,然后在场景上面工具栏内,找到TilePalette来打开调色板


打开调色板


新建的调色板进行命名

创建时候会提示保存路径,选择Tiles文件夹

把前面的Tile拖入调色板


选中笔刷,就可以根据指定的Tile,来刷存在感,例如在上面场景内可以随意刷,例如刷个Wesky


资源里面的Tile属性,有一个每单位100像素点。


把每个单位100像素,改为64像素,应用以后,就可以看到场景内的空隙就没掉了,不会留下空白了。


选择环境下的floor几个文件,一起选中,然后精灵模式设为Multiple


然后选择Slice,选择GridByCellGrid


选择3*3

然后就可以发现可以展开,里面有9个图案

然后继续对其他五个进行同样的拆分。

完了以后,对所有6个资源,拖入到调色板内。如果提示保存路径,就保存到Tiles文件夹内。如果资源显示的不是填满状态,则跟上面一样的方式,修改对应的单元像素点数量。


快速选择、移动操作。


快速平铺操作


快速填充

回到Hierachy目录下,可以看到Ruby、Grid、Tilemap的属性里面,坐标也包括Z轴,虽然是2D,但是实际上Z轴是我们正视的方向。所以也存在层次。如果都是0,Unity也会存在渲染先后问题,有可能导致需要显示外面的,因为先渲染,所以就被覆盖的情况。


可以修改Z轴来显示不同层级,但是毕竟是2D项目,这样做不太友好。所以有一个层级的概念。orderbylayer,数值越大,渲染越晚,以此来达到分层次渲染来显示的目的。


例如tilemap,地面一般是最底层,此处假设设为-10


然后Ruby本身可能是隐藏的,现在就出现了

引入一个立方体

这个时候发现,Ruby爬到箱子上面穿过,这个不太符合正常规律。


打开项目设置


Graphics下面的Camera设置,把模式设为自定义


把Y轴设为1,其他为0,代表按照Y轴渲染进行排序

此时,可以看到Ruby不会跑到箱子上面了。

不过此时,角色穿过以后,会发现身体部位,有的在箱子一边,有的在另一边,穿模了。那就继续改。Ruby觉得属性的SpriteSortPoint把默认的Center改为Pivot.如果是center,说明轴心点是中心点,所以是以中心点进行判断的,就可能存在身首异处。


环境资源内,把箱子的属性Pivot也设为底部



最终效果


立方体场景内的也设为Pivot


为了方便后续操作,此处把箱子作为预制体。方式:场景的箱子,拉到资源下面,就可以变成预制体了。预制体,可以用于,在预制体内修改,使用预制体的场景内容,都会同步更新。


设置好以后,现在看Ruby,可以发现穿越自然很多了


虽然穿越自由了,但是实际上的世界,是不允许穿越的。所以接下来要添加刚体组件和碰撞器来实现不穿模。

给角色添加RigidBody2D刚体组件。


然后把Ruby也设为预制体。

设为预制体完成以后,先启动看下带上刚体组件的效果。发现Ruby走向了深渊,受到重力影响。


2D这个不需要重力,所以需要把重力系数改为0.数值指的是重力的倍数。

对箱子新增碰撞器BoxCollider2D,一般对运动的物体需要提供刚体组件,给静止物体只提供碰撞器。如果需要碰撞的两方,都需要有碰撞器。如果运动的物体不提供刚体组件,“可能”导致碰撞失效。

给Ruby也提供碰撞器


把超出范围的部分,进行调节


然后把场景内的更改,应用到预制体内


对Ruby也做同样的调整和应用

现在启动程序,可以看到还有bug,存在角色抖动和旋转问题。


刚体组件内冻结角色Z轴旋转

接下来解决Ruby抖动问题:刚体组件检测到Ruby和箱子重叠,把Ruby移出碰撞器外;但是人工按键控制Ruby移动,又会导致Ruby进入,从而导致角色抖动。修改代码,最后通过刚体.MovePosition来移动到指定位置


继续修改箱子碰撞器,把碰撞范围缩小。不然角色到达箱子边缘就会被挡住了。


对角色也要做调整,调整到脚底区域。调整完毕记得应用到预制体进行覆盖。


现在可以看到,角色遇到箱子可以正常了,不会抖动,也不会旋转了。


现在配点场景

运行会发现,角色会掉河里。

需要控制角色不掉河里,并且支持快速操作的方法,使用Tilemap碰撞器。Tilemap新增Tilemap2D碰撞器。


选中资源下面tiles文件夹内除了带河流的所有资源,然后把碰撞类型,统一设为None。原先布局看不到缩略图,所以布局可以自己调整一下。


启动测试过程省略,可以看到不会掉河里了。但是还存在一个问题是,看到河内碰撞器太多,对资源是一种浪费。


对Tilemap新增联合碰撞器组件CompositeCollider2D


然后,回到tilemap的2D碰撞器,把CompositeOperation设置为Merge。其他几个选项说明如下:

None:不进行任何合并操作。每个Tile都将保持其单独的Collider。

Merge:将相邻的或重叠的Colliders合并成一个大的Collider。这通常用来减少物理计算的复杂性和提高性能。

Intersect:只保留重叠部分的Collider。这种操作较少见,但可以用于特定的碰撞检测逻辑。

Difference:从一个Collider中减去与另一个Collider重叠的部分。这可以用来创建复杂的碰撞形状。

Flip:这个选项并非标准的合并方式,可能用于反转Collider的合并逻辑,但在标准的Unity文档中并不常见,具体效果可能取决于具体的实现。


这个时候,可以看到场景内的碰撞器网格被合并在一起,形成一个大的碰撞器了,减少了不必要的纹路。


接着再把Tilemap的刚体组件的BodyType类型设置为静态Static。三种状态说明如下:

Dynamic:这是最常用的选项,使物体受到所有物理效果的影响,包括重力和碰撞。动态物体可以自由地移动和旋转,并且它们的行为将由力、扭矩和外部影响(如碰撞)决定。

Kinematic:运动学物体不受力和碰撞的影响,但可以通过改变其位置和旋转来影响其他的动态物体。通常用于控制物体的运动,如平台或由代码驱动的物体,而不是通过物理引擎自然响应力。

Static:静态物体基本上是不移动的物体。它们不会因为受力而移动或旋转,但可以用来作为场景中的不动障碍物或地面。例如,墙壁和地板通常设置为静态,因为它们不需要移动也不受重力影响。


给Ruby设置初始化的生命值、以及定义最大生命值。


新增一个更新生命值的方法

Clamp方法说明:

方法有三个参数:

value:需要被限制的值。

min:允许的最小值。

max:允许的最大值。

带入上面的代码,如果_currentHealth+value小于0,会返回0;如果大于_maxHealth,它会返回_maxHealth;如果在0和_maxHealth之间,它会返回_currentHealth+value的值。

继续优化其他代码,用于方便操作.


新增草莓控件,用于给角色不满血状态下,恢复血量使用。

给草莓添加碰撞器,并且勾选触发器。

接着新建一个草莓的脚本代码,例如HealthController.然后挂载给草莓控件,当做草莓的一个组件。


这个时候,触碰草莓应该是穿过去的,不会有效果。所以新增一个进入草莓刚体组件时候的方法,方法自带,我们只需要写内容即可。


ruby里面新增一个属性,用来只能获取当前生命值的用途

Health控制器当前代码如下


这个时候,如果血量不满,就可以吃掉草莓。但是如果血量是满的,就会穿透。具体演示就不放了,大佬们到这儿应该差不多都可以自己玩了。

接下来,继续添加伤害区域


然后新增碰撞器和触发器

新增伤害区域脚本,并绑定给伤害区域控件

ruby里面新增一些属性和方法,用于让ruby在伤害区域内,可以持续性掉血

一些无敌时间的设定,让Ruby不会瞬间挂掉;以及定时操作的设定。


现在把ruby的刚体组件休眠关闭,防止ruby休眠(导致碰撞效果失效)

伤害资源里面,把Mesh类型设置为FullRect

然后把控件的Draw模式设置为Tiled.三个选项含义分别是:

Simple-这个选项通常表示对对象的处理保持基本和简单,没有复杂的变化或额外的图像处理。

Sliced-这通常用于处理需要九宫格缩放(9-slicescaling)的图像。这种方法可以让你的图像在拉伸时保持边缘和角落的完整性,常用于UI元素如按钮和面板。

Tiled-这个选项允许图像在空间中重复平铺,而不是拉伸。这适合那些需要在较大区域内保持图案一致性的纹理或图像。


TileMode选择适配器模式,可以在缩放时候自适应


AutoTilling勾选以后,碰撞器也会自动跟随物体拉伸而同步拉伸


添加机器人,并添加碰撞器


再新增刚体组件,重力0,冻结Z轴


机器人资源,Pivot设置为自定义

设置轴心点等调整

修改碰撞器大小


新建机器人脚本,然后挂身上

当前运行效果如下。观察当前血量,满血吃不到草莓;碰到机器人,血量-1,再返回去,就可以吃掉草莓,然后回血。

由于篇幅限制,后半部分,后续择时再发布。后半部分内容前瞻:包括动画设置、粒子效果、虚拟相机、武器开发、UGUI、射线检测、音效、打包与发布等。

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐