您现在的位置是:首页 >学无止境 >Unity 新建你的第一个游戏,以及如何按WASD控制角色运动 (Unity Demo2D)网站首页学无止境

Unity 新建你的第一个游戏,以及如何按WASD控制角色运动 (Unity Demo2D)

Nesb01t 2024-06-21 06:01:02
简介Unity 新建你的第一个游戏,以及如何按WASD控制角色运动 (Unity Demo2D)

初始化项目

当你打开 Unity Hub,初始化一个 2D 项目,进入了 Unity 编辑器,你会发现在 左侧

  • 一个叫 SampleScene (或者其他) 的场景
  • 场景下有一个 Main Camera,主相机

这就是一个新建的 2D 项目自带的内容。

在这里插入图片描述

新建角色物体

在 Main Camera 同级目录新建:2D Object - Sprites - Capsule,这里 Capsule 是精灵的种类,我们在后面都是可以自行更改的,Capsule 是胶囊形状的物体,在碰撞处理时会更润一点。

在这里插入图片描述

这里我给我的 精灵(Sprites) 命名为 PlayerObject,随后你会发现 右侧,有一大堆这个精灵的属性,比如说位置速度旋转角之类的:

  • Transform 每个游戏对象都包含一个这个组件,控制其位置、移动
  • Sprite Renderer 给精灵赋予渲染 2D 图片的能力

试着修改 PositionRotationScale 看看效果!

在这里插入图片描述

游戏资源管理

试着导入资源

低头看看下面的栏里,这里是你的游戏资源,包括脚本,图片都放这里了:

  • Assets 当前游戏使用的资源
  • Packages 通用的资源,可能别的游戏也可以用的 ( 这里可能存在误导性,请读者自行理解

所以你只需要把图片什么的往里面拖进去就是导入资源了,非常简单。

在这里插入图片描述

试着管理资源

刚刚创建出来的精灵长得确实像一个胶囊,如果不是特殊情况,玩家不应该是长那样的。

在这里我在 Assets 中新建了几个文件夹,只是一个 Demo 大概了解意思就行,不喜勿喷 (但文件管理层级确实是需要上心设计的,否则到后面会变得混乱,极其不方便使用,极其影响效率)

可以看到这里我导入了一个图片,叫 character_0001

在这里插入图片描述

试着使用资源

接下来我们直接让胶囊变成这个小怪物的样子:

也非常简单,你把你的资源里面的图片,拖到 Sprite Renderer - Sprite 里面就好了,没有多余的操作:

在这里插入图片描述

脚本是啥

如果你写过一些简单的游戏,你会写过一些脚本,比如说 碰撞检测角色移动,在 Unity 中这些脚本作为 独立的 .cs 文件 放置在资源文件夹中,当你需要这个功能时,就可以把脚本挂在某个物体上,让他实现一些能力

我们拿 碰撞检测 举例,在简单的游戏中,一个脚本代码文件就可以控制所有的游戏内容。每一帧检测:

  • 是否有碰撞到怪物
  • 碰撞到了是否结束游戏
  • 碰撞到星星给本次游戏加分
  • 渲染玩家,怪物,星星
  • 渲染屏幕上面的分数

等等诸如此类的内容。

但在 Unity 这样的较大的游戏客户端开发中,我们将会需要把这些内容完全解耦,即:

  • 每个物体都拥有一个 碰撞系统 脚本
  • 游戏的结束和开始单独由 游戏流程管理器 来实现,这个管理器可以是个单独的物体,也可以 写成一个脚本,挂载在玩家对象上
  • 加分系统单独写成一个 加分系统管理器,玩家拥有 <调用加分系统中的功能> 能力的脚本,当玩家的碰撞系统检测到星星时,就调用加分系统中的 加分销毁星星
  • 星星也有 碰撞系统,检测到 被碰撞 了就直接紫砂

如果你不这样写,那某个文件代码行数怕是要上万了。另一方面,我们也能从这种实现方式中窥见游戏性实现的可能,以便游戏的策划设计优化等等涵盖前中后期的工作。

新建脚本

也很简单,在这个地方右键然后 Create - C# Script 就可以了~

在这里插入图片描述

编辑脚本

我们可以使用 Visual Studio 或者 VSCode 进行 C# 脚本的编辑,多数人使用 Visual Studio,工具链更完善。

如果您对如何使用更轻量的 VSCode 感兴趣,可以参考我的另一篇笔记:如何使用 VSCode 编辑 Unity + C# 脚本

打开你刚刚创建的脚本 (如果你使用VS,文本内容也是一样的,这者没有实质上的区别):

  • Start() 当脚本被初始化完毕时执行的
  • Update() 每一帧都会执行的
    在这里插入图片描述

行为逻辑

由于我们使用的是 2D 模板,此时我们的 PlayerObject 也没有挂载重力系统,碰撞体系统,那么想让 PlayerObject 移动无非是修改玩家的位置 (x, y, z)

参考一下大多数游戏的流程:按下A,玩家往左走

所以有可能初学者会认为:写一个函数来检测按下A,当玩家按下A的时候,玩家开始往左走

就目前我们仅有2个函数块 StartUpdate,不涉及线程池等等操作的话,显然这样是不容易实现的,一个可能的正确的方式是:每一帧都检测玩家是否按下了某个按键,如果按着就移动一点点

按键检测

我们会需要一个 Unity 提供给我们的静态类 (Static Class),或者叫做工具类 (Utils),这个类是 Input,专门用来读取按键输入,这里需要您具有面向对象编程经验:

键入 Input,通过智能提示可以发现这个静态类中提供的实现:

在这里插入图片描述

获取按键

通过这个函数会返回某个按键是否处于按下状态 (bool)

Input.GetKey(KeyCode.A)

那么我们只需要这样就可以不停获取 A 的按键信息了

void Update() {
	bool isKeyDown = Input.GetKey(KeyCode.A);
}

移动位置

这里我们需要用到 PlayerObject 对象自带的组件 transform,这样调用来实现对象的 移动

  • Time.deltaTime 是这一帧渲染所经历的时间,这样在不同游戏帧数下,对象的移动速度才会一致(参考 Terraria 的跳帧算法)
  • Translate() 的三个参数分别是 x, y, z,你也可以输入一个 Vector 或者别的,详见 Translate 的函数原型
transform.Translate(1.0f * Time.deltaTime, 0, 0);

★ 最终代码 (有基础请直接跳到这)

这就是最终实现功能的代码:

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。