Unity 教程整合:快速上手 2D 游戏开发,涵盖角色移动、脚本组件等基础内容

昵称 3个月前 45浏览 0评论

前言:本文教程结合了Unity官方教程以及其他线上资源教程,旨在帮助你更快的入门,减少你观看理论性较强的教程或者视频较长的教程的时间。

本文参考了如下相关文献或内容:

SIKI视频教程:Unity2D官方入门案例-Ruby's Adventure:

Unity官方文档教程:Ruby's Adventure: 2D Beginner

如果对官方教程或者视频教程感兴趣可以参考上面两个教程入口,如果喜欢快速上手,看我下面动手实验部分可能会更快。

本文是上半部分的基础内容,包括:控制角色的移动、脚本组件开发、Tilemap的使用和地形绘制、地形碰撞器、物理系统(碰撞器、刚体组件等)、角色生命值恢复和生命值损失触发、预制件等。

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

导入相关资源包,我直接从Siki的免费课程里下载的资源包,资源链接:

该资源包中包含了官方免费的Ruby Fox以及其他可供本项目实际使用的相关资源。

将 Ruby 图像拖入 Art 文件夹

可以拖入场景中

选择Ruby,你会看到图像格式自动转换为2D和UI格式。

新建一个脚本文件夹 Scripts,并在其中添加一个新脚本 RubyController

将脚本放入 Ruby 控件属性中,使其成为组件。

进入项目配置项

在输入管理器中可以设置一些参数,这些参数也可以通过代码获取,比如水平参数、垂直参数等。

双击打开之前的C#脚本代码,添加代码如下,用于控制主角的移动,使用Time.deltaTime来实现平滑移动。

关于deltaTime的解释,请参考GPT的说明:

2D默认帧率为60FPS,启动时可更改,一般情况下无需更改,以下仅为示例。

场景移动时,可以预设步长。设置步长,点击场景中的工具栏,有一个增量捕捉

将步距设置为 1

测试一下效果,随便拖一个到环境中,然后按Ctrl+d复制一个,再按Ctrl+鼠标拖动,可以看到它自动移动1个单位(一个网格长度),并且自动对齐。

删除上面的测试并添加新的 Tilemap

会自动创建一个Grid,并在Grid下创建一个Tilemap。

Grid可用于将游戏对象均匀分布在网格中;Timemap是由Tile组成的网格地图。

在Assets下新建Tiles文件夹,然后在文件夹中新建Tile并重命名为FirstTile

将资源中的Tile图片拖拽到环境目录

然后为Tile设置一个精灵,并将Tile图片资源对象拖过来。

选择Hierachy的Tilemap,然后在场景上方的工具栏中,找到Tile Palette打开调色板

打开调色板

命名新调色板

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

将之前的 Tile 拖入调色板

选择画笔,就可以根据指定的Tile来刷存在感了。比如在上面的场景中,你可以随意刷,比如刷一个Wesky

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

但是下面的图片资源大小是64*64,所以在绘制上面的场景的时候,遇到了填充不完整的问题。

将每个单元从100像素改为64像素。应用后,可以看到场景中的缝隙消失了,没有留下任何空白。

选择环境层下的几个文件,一起选择,然后设置向导模式为多个

选择第一张图片并打开编辑器

然后选择切片并选择按单元格网格

选择 3*3

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

然后继续对其余五个进行同样的分割。

之后将6个资源全部拖入调色板,如果提示保存路径,则保存到Tiles文件夹即可,如果资源没有显示为填满,则按照上述方法修改相应的单位像素数。

快速选择和移动操作。

快速平铺操作

快速填充

在 Tilemap 中操作需要点击 Edit 按钮,如果不点击则只能在场景中操作。

回到 Hierachy 目录,可以看到 Ruby、Grid、Tilemap 的属性中,坐标也包含了 Z 轴,虽然是 2D,但是 Z 轴其实就是我们看的方向。所以这里也有层级关系,如果全部为 0,Unity 也会出现渲染顺序问题,可能因为先渲染了,导致外面被覆盖了。

取消选中 2D,您可以看到它实际上是一个 3D 场景,但相机始终直视前方。

可以修改Z轴来显示不同的层级,但是因为是2D项目,这样不太人性化。所以就有了层的概念。按层排序游戏开发,值越大越靠后渲染,从而达到分层渲染的目的。

比如在tilemap中,地面一般是最底层,所以这里我们假设设置为-10

那么 Ruby 本身可能已经被隐藏了,现在看来

引入立方体

这时候才发现Ruby是爬上箱子穿过去的,这不符合正常规则。

打开项目设置

在“图形”下的“相机”设置中,将模式设置为“自定义”

将Y轴设置为1,其他设置为0,表示按照Y轴渲染排序。

此时,你会看到 Ruby 还无法在盒子上运行。

但是角色穿过箱子之后,会发现身体有的部分在箱子的这边,有的部分在另一边。那就继续修改吧。Ruby 认为应该将属性的 Sprite Sort Point 由默认的 Center 改为 Pivot,如果是 center 就代表枢轴点是中心点,所以以中心点为判断依据,身体和头部可能会分离。

在环境资源中,将框的 Pivot 属性设置为底部。

打开 Ruby 资源的属性,然后打开精灵编辑器

设置Ruby,使其轴线位于脚部,并设置图片大小为合适的图片,避免周边留白过多,影响后续操作。

最终结果

立方体场景也设置为 Pivot

为了方便后续操作,这里将盒子作为一个预制件来使用。方法:将场景中的盒子拖到资源下,即可将其变为预制件。预制件可以在预制件内部进行修改,使用预制件的场景内容也会同步更新。

盒子的精灵编辑器打开游戏开发,并且它的枢轴点发生了改变。

设置好之后,现在我再看Ruby,发现时间旅行自然多了。

虽然遍历是自由的,但是现实世界是不允许遍历的。所以接下来我们需要添加刚体组件和碰撞器来实现非遍历。

给角色添加 RigidBody 2D 组件。

然后将 Ruby 也设置为预制件。

预制件完成后,启动它,看看刚体组件的效果,发现Ruby正在向深渊走去,受到重力的影响。

2D不需要重力,所以需要将重力系数改为0,该值指的是重力的倍数。

为盒子添加新的碰撞器 Box Collider 2D。一般运动物体需要提供刚体组件,静止物体才提供碰撞器。如果双方都需要碰撞,则需要提供碰撞器。如果运动物体没有提供刚体组件,可能会导致碰撞失败。

为 Ruby 提供碰撞器

然后选择该框并检查是否有任何超出碰撞范围的资源。

调整超出范围的部分

然后将场景中的更改应用到预制件

进行同样的调整并应用于 Ruby

现在启动程序,可以看到还存在一些bug,比如人物抖动,旋转的问题。

在刚体组件中冻结角色的 Z 轴旋转

接下来需要解决 Ruby 抖动问题:rigidbody 组件检测到 Ruby 与盒子重叠,将 Ruby 移出碰撞器;但手动按下按钮控制 Ruby 移动会导致 Ruby 进入,从而导致角色抖动。修改代码,最后使用 rigidbody.MovePosition 移动到指定位置

继续修改盒子碰撞器,减小碰撞范围,否则角色到达盒子边缘时会被挡住。

调整角色,尤其是脚下的区域。调整后,记得将其应用到预制件上以覆盖它。

现在你可以看到角色可以正常遇到盒子,而不会摇晃或旋转。

现在让我们来设定场景

如果你运行游戏,你会发现角色会掉进河里。

需要控制角色不掉入河中,并支持快速操作。使用Tilemap碰撞器。Tilemap添加了Tilemap 2D碰撞器。

选择Resources下tiles文件夹中除河流之外的所有资源,然后设置碰撞类型为None。看不到原始布局的缩略图,所以可以自行调整布局。

省略启动测试过程,可以看到不会掉进河里。不过还是有个问题,就是河流里的碰撞器太多了,比较浪费资源。

为 Tilemap 添加了 Composite Collider 2D

然后,返回到 Tilemap 的 2D 碰撞器,并将 Composite Operation 设置为 Merge。其他选项如下:

此时可以看到场景中的碰撞器网格被合并到一起,形成了一个大的碰撞器,减少了不必要的纹理。

然后将Tilemap的刚体组件的Body Type设置为Static,三种状态如下:

为 Ruby 设置初始健康值并定义最大健康值。

添加更新健康值的方法

夹紧方法说明:

用于限制某个值,使其保持在指定的最小值和最大值之间。此方法可以确保变量的值不超过设定的范围,在游戏开发中非常有用,例如控制角色的位置、设置相机的视图边界等。

Mathf.Clamp 方法有三个参数:

值:要限制的值。

min:允许的最小值。

max:允许的最大值。

上述代码中,如果_currentHealth+value小于0,Mathf.Clamp 将返回0;如果大于_maxHealth,则返回_maxHealth;如果介于0和_maxHealth之间,则返回_currentHealth+value的值。

继续优化其他代码,以方便操作。

增加了新的草莓控件,用于在角色生命值未满时恢复角色生命值。

为草莓添加一个对撞机并检查触发器。

接下来,新建一个Strawberry脚本代码,例如HealthController。然后将其作为Strawberry的组件挂载到Strawberry控件上。

此时触摸草莓应该会穿过去,没有任何效果。所以添加一个方法来输入草莓刚体组件。方法自带,我们只需要写内容即可。

Ruby 中添加了一个新属性来获取当前健康值

Health 控制器的当前代码如下

这时候如果血量没满,就可以吃掉草莓,血量满了就会穿透,具体就不演示了,各位高手应该自己会玩了。

接下来,添加受损区域。

然后添加碰撞器和触发器

添加了新的伤害区域脚本,并将其绑定到伤害区域控制

在ruby中添加了一些新的属性和方法,使得ruby在受到伤害的区域持续损失生命值

一些无敌时间设定,以防止Ruby立即死亡;以及定时操作设定。

现在关闭Ruby刚体组件的休眠,避免Ruby休眠(导致碰撞效果失效)

在损坏资源中,将网格类型设置为全矩形

然后将控件的Draw模式设置为Tiled,三个选项含义如下:

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

勾选Auto Tilling之后,碰撞器会自动跟随物体同步拉伸。

添加机器人并添加对撞机

添加新的刚体组件,重力0,冻结Z轴

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

设置枢轴点和其他调整

修改碰撞器大小

创建新的机器人脚本,然后附加到机器人身上

机器人脚本编辑,具体内容如下。

目前运行效果如下,观察当前生命值,生命值满时不能吃草莓,遇到机器人时生命值减1,返回后可以吃草莓恢复生命值。

由于篇幅所限,下半部分将稍后发布。下半部分内容预告:包括动画设置、粒子效果、虚拟相机、武器开发、UGUI、射线检测、音效、包装发布等。

如果您觉得我的教程比其他教程更方便快捷,或者对您有帮助的话,请点赞、转发或者观看,谢谢您的支持!

点击关闭
  • 客服QQ:

    744926664

    -------------------

分享:

支付宝

微信