本篇以unity官方课堂教程为参照,主要以2D游戏开发并分享自己的经验。
我自己使用的编译器版本为:2021.3.27f1c2
本篇文章不会专门去写关于unity基本界面的介绍和编程语法上,而是重点在组件和应用上。
Ruby's Adventure: 2D 本篇文章依据此处来说下自己的学习心得
https://learn.u3d.cn/tutorial/unity-ruby-adventure
根据要求在Asset Store下载相关资源包,然后就让我们开始吧!
下载好资源包后将人物角色图片拖入到Hierachy目录中,就可以发现我们的任务出现在Scene视图中了。
可通过拉伸来确定合适的大小,这里就不多说明了。
此时我们可以看到右边的组件栏好像多出来了什么东西。
Transform组件
在Transform组件中有Position、Rotation、Scale这三个属性。(这是最基础且不可隐藏的组件)
Position:表示现在人物的位置。X(水平)、Y(垂直)、Z(深度)。这个游戏是2D游戏所以Z轴为0。
Rotation:表示人物的旋转方向。XYZ分别表示方向上的旋转。
Scale:表示人物大小的缩放。可以向不同方向进行拉伸。
OK!我们先了解这一个组件,开始写脚本吧,编译器,启动!
在Project中创建一个文件夹,命名为Scripts(要养成好习惯!),之后进入该文件夹,创建一个C# Script的脚本。
启动脚本的时候我们的编译器将会被打开,我们先把目光放到两个函数上面。
Start函数与Update函数
Start函数:Unity仅在游戏开始的时候执行一次Start函数中的代码。
Update函数:Unity在每帧执行Update函数的代码。Update函数可以编写游戏中连续发生的操作(例如读取玩家的输入,移动游戏对象或者计算经过的时间。)
刚好我们现在想让我们的人物随着时间发生移动,那我们根据上面的组件看,与位置相关的一个组件是Position,我们想可以不可以通过改变Position的XYZ三个参数来实现角色的移动。
试试就逝世。对比两个函数,我们应该在Update函数中写入代码。
void Update()
{
Vector2 position = transform.position;
position.x = position.x + 0.1f;
transform.position = position;
}
我们对游戏对象运动的代码就写出来了,在这里我们的思路:
- 声明一个变量来存储Position的XY轴的参数。
- 对变量中的一个坐标轴进行修改。
- 将改变后的变量传回到Position之中。
Vector2变量
我们可以看到在代码中出现Vector2的关键字,这个是一个数据类型,不同的数据类型用来存放不同的数据,Vector2是存储两个数字的数据类型,因为此游戏为2D游戏,所以我们不需要储存Z轴的位置信息,移动游戏对象的第二行代码我们加上了0.1f表示0.1个单位,这样每一帧都会向右移动0.1个单位(正值游戏对象将向右移动,负值则向左)。
在这里我们可以注意到,我们可以直接使用Transform组件,并且这个组件是可视化的,在之后的添加其他组件中也可以直接使用,大大方便了我们游戏的制作。
最后我们将编写的脚本直接拖拽到游戏对象的Inspector之中。
此时我们可以注意到在最下面多出来我们的脚本组件,表示脚本添加完毕,此时我们让Unity运行我们的程序吧!
不好!被我们放入脚本的角色瞬间飞出这个屏幕,虽然是实现了物体的移动,但是怎么感觉怪怪的。由于是每帧移动0.1个单位,在游戏中通常在一秒内就移动了30-60帧,所以才会移动得很快。
但是在游戏中我们通常需要自己去操控角色,所以我们要重新修改我们的代码了。
角色控制器和键盘输入
为了实现对角色的控制,我们将使用Unity输入系统。该系统包含输入设置和输入代码
查看默认输入设置,这些设置可以定义游戏中的输入类型。
- 找到Edit > Project Setting,然后选择Setting窗口中Input Manager页面
Input 页面列出所有玩家输入控件(例如,游戏手柄上的一个按键)的 Axes 值。值的范围从 -1 到 1(具体值取决于玩家执行的操作)。例如,对于游戏手柄上的控制杆,可以将水平轴设置为:
- -1(控制杆在左侧时)
- 0(控制杆在中间时)
- 1(控制杆在右侧时)
对于键盘按键,以 2 个键来定义轴:
- 负值键,被按下时将轴设置为 -1
- 正值键,被按下时将轴设置为 1
如果查看水平轴(Horizontal),可以看到 down(表示向左箭头键)在 negative button 上,而 up(表示向右箭头键)在 positive button 上。
那么我们将用这个输入系统来实现我们的角色移动。
void Update()
{
float horizontal = Input.GetAxis("Horizontal");
Debug.Log(horizontal);
Vector2 position = transform.position;
position.x = position.x + 0.1f * horizontal;
transform.position = position;
}
一开始看到这一组有点懵,不过仔细分析还是很简单的。
GetAxis函数
GetAxis函数也是一个函数,其内部的工作已经完成,我们要做的就是直接进行调用就好。
圆括号之间的单词被称为参数,向函数提供信息的目的是指点函数应该执行的操作,在这里我们想要获得一个水平轴的值,所以告诉这个函数这个轴的名称(Horizontal),注意要放在引号之间以说明这是一个单词而不是关键字。
第二行代码出现Debug,这将方便我们在Unity中Console控制台查看那些不可视的数据变化。
适当调整移动得代码,将对象移动得大小乘以轴的值:
如果你按向左键,则轴将为 -1(即移动距离为 position.x + -0.1f;)。Ruby 将向左移动 -0.1。
如果你按向右键,则轴将为 1。Ruby 将向右移动 0.1。
如果没有按下任何键,则轴将为 0 且 Ruby 不会移动(0.1 * 0 等于 0)。
现在可以开始运行游戏来看下是否实现了角色左右方向的移动了!
那么垂直方向的移动也可以在输入系统重找到,就是Vertical啦!
时间与帧率
在Start函数中加入两行代码。
void Start()
{
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = 10;
}
这样做之后Unity每秒渲染10帧,也就是每秒调用10次Update函数,由此我们可以发现一个隐藏的问题,对于不同的电脑来说,同一个游戏所带来的帧率不同,在移动时候速度将会发生差异,这样将会影响游戏的体验。
所以对于这样的情况我们需要明确应该是以单位/秒来进行移动,而不是单位/帧,所以我们要改变移动得脚本。
首先将Start函数中的两行代码注释掉。
更新Update函数的代码:
void Update()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 position = transform.position;
position.x = position.x + 0.1f * horizontal * Time.deltaTime;
position.y = position.y + 0.1f * vertical * Time.deltaTime;
transform.position = position;
}
这里发现我们乘上了一个Time.deltaTime。deltaTIme是一种变量,Unity将会渲染一帧所用的时间填充到此变量之中。在我理解里比如每秒调用Update函数60次,那么deltaTime相当于1/60的分母,用来将这些帧数细分,这样一秒就可以移动0.1个单位了。
现在我们终于能控制我们的角色了!