从零开始独立游戏开发学习笔记(四)--Unity学习笔记(一)--Unity基础(一)

3,316 阅读8分钟

虽然说 Unity 和 C# 的学习可能是我所有要学的东西中最简单的。但那只是一个相对的概念,并不代表这些东西的学习本身是一个简单的事情。很多人学了七八年也不敢说自己精通 Unity 或者 C#。说它们简单只不过是相对于绘画和音乐来说,因为后两者可能穷极一生都无法精通。

Anyway,对于 Unity 我并不需要达到一个精通的水准。我只需要能够把自己的想法实现出来就行。而目前我的目标也只是看完 brackeys 的教程和 Unity 文档而已。

1. 安装

1.1 如何逃离中国特供版 Unity

早有耳闻中国 Unity 坏事做尽。于是安装前搜到了这么一个 网站。域名很有意思。

1.2 安装

  1. unity hub:问我要不要转 beta 下载器。转了,好看多了,看来像 unreal 学习了很多。
  2. unity 本体的下载:看了下官网的版本说明,beta 版比稳定版本多了功能,但并不是说不稳定。alpha 才是不稳定的可能会出 bug 的版本。所以我下载了 beta 版本。
  3. 附加下载选择如下: image.png

1.3 下载失败

疯狂下载失败,而且下载失败需要从 0 开始重新下载,绝了。
下载花了两个小时,今天(29 号)估计没法更了。

2. 起步

新建一个 3d 空项目。然后就能看到 unity 的界面。长这样: image.png

2.1 UI 简单介绍

2.1.1 hierachy

左边的 panel 显示了当前项目的 hierachy。

  1. 可以看到默认有一个叫做 sampleScene 的东西,顾名思义这是个 scene(unity 里的 scene 就是关卡)。
  2. 然后其下方可以展开的两个叫做 object。一个是主相机,一个是定向光。

2.1.2 inspector

  1. 点击任意一个 object 后,右边就会显示一些东西。
  2. 这些东西也是有 hierachy 的,那些可展开的东西叫做 components(组件?)。component 可以使 object 做各种各样的事情。展开里的东西叫做 Properties(属性)。

2.1.3 project

  1. 下方很长的这个是 project panel。里面放着游戏 asset,可以从这里把 asset 直接拖进屏幕。从而显示在 hierachy 里。 右上角可以更换视图显示,传统艺能了。

2.2 创建地面

  1. 在 hierachy 视图里新建一个 3d cube。

在中央视图里选择物体后按 f 可以自动聚焦到该物品上(过去式)。
现在是双击 Object 聚焦。

  1. 物品出现的位置不是我么想要的,所以选择 cube 后,在 inspector 里右键 transform 这个 component,点击 reset。这样物品的位置和缩放就被重置了。
  2. 中央界面上方有几个 tab,代表着不同视图,选择 game 后就会变成游戏实际看到的画面。这些视图 tab 也可以拖动改变布局。比如说把 game 拖动到右边,这样就可以同时看到游戏画面的样子了。我们就这么做。 image.png
  3. 改变一下 transform 让其变长变宽。就成了一个地面。在 inspector 左上方可以更改 object 的名字。这里改成 ground。

2.3 创建角色

  1. 依旧用 cube 来作为游戏角色。创建后 reset。你看,之前的地面我们 reset 过了,现在的角色我们也 reset。那么调整两者之间的距离关系就简单多了。

2.3 material

角色现在和地面一样是白色,并不好区分。所以要用 material 改变角色的外观。

  1. material 是 asset,要在 project panel 里创建。
  2. material 也有很多属性可以在 inspector 里更改。
  3. 把 material 拖到 object 上就可以用了。在 material 里更改的属性可以实时显示在屏幕上。

2.4 添加物理

  1. 把角色往上拖一点。点击中央上方的 play。发现无事发生,cube 并不会掉下来。因为我们什么都没做,什么都没加。
  2. 所以我们得让这个 object 和 unity 物理系统交互。
  3. 之前讲过 component 使得 object 做各种各样的事。因此我们需要给 object 一个新的 component。
  4. 我们加上 RigidBody 这个 component,这样我们的 cube 就可以掉下来了。然后我们旋转一下以让物品掉下来更有趣。(qwerty 快捷键可以快速更换拖动,位置,旋转,缩放等工具)

2.5 component

再好好看看 cube 的 components。除了我们添加的 RigidBody。还有很多别的。

  1. transform 不用说了,基本每个 object 都有的基本属性。
  2. Mesh Rendered。渲染 object 的,如果去掉勾选。物品就不会显示在屏幕上。但是仍然存在,只是不显示。
  3. Box Collider。顾名思义,碰撞相关的组件。去掉勾选后物品就没有碰撞效果了。在有重力的时候,会无视地面一直往下掉。和其他物品碰到也不会相互影响。Box Collider 和 RigidBody 共同提供了真实物理效果。
  4. Mesh Filter。没什么好说的,只有一个属性,改变形状。如果我们改成球体。注意由于我们的组件里依然还是 Box Collider。因此碰撞体积还是 Box。可以删掉 Box collider 换成 Sphere Collider。

play 状态的时候仍然可以更改属性。但是所有的更改在退出 play 状态的时候都会撤销。

2.6 skybox

在 camera 中可以更改 skybox。(clear flags 属性中更改)

2.7 maximize view 快捷键

shift + space 可以把鼠标位于的视图放大到最大。类似于 Adobe 系列的 ~ 键的作用。

3. C# 初接触

也不算初接触吧,稍微知道一些语法,但是也就一点点。

3.1 移动 Script

Unity 里通过 Script 来給 Object 添加代码。
Script 其实也是一种组件。 因此还是通过 Add Component 来添加。我们在我们的 cube 上添加一个 Script 组件。
添加完毕后可以看到一个 Script 文件在 project panel 里出现。这个脚本自然也可以放到其他的 Object 上。
可以看到此时我们的 cube 上有了一个 Script 组件。双击组件下面属性中的文件名就可以打开代码编辑器(基本都是 vs)来编辑它。(或者双击 project panel 上的文件也行)
image.png

3.1.1 Start()

start 函数(还是方法?语法不太懂)里的代码会在游戏运行前执行,这个看注释也能够知道。 用 Debug.Log() 来打印。看起来很像 console.log(),实际上,当你回到 Unity,运行游戏的时候。可以看到正是下方的 console panel(project panel 旁边的那个 tab)里打印了你要打印的东西。

3.1.2 链接其他组件

还是之前的 Script 文件,这次我们在 start 上方新建一个变量,类型为 RigidBody,很明显这是为了控制 RigidBody。变量随意取个名叫 rb。
image.png
回到 Unity,可以发现 Script 组件里多了一个 rb 属性。不过值是空的(None)。
image.png
我们想让这个 rb 变量和我们 cube 上的 RigidBody 链接在一起,从而达成对 RigidBody 的控制。操作方式很简单,直接把 cube 上的 RigidBody 组件拖到 None 值上即可。(Unity 会有类型检测,别的组件你也拖不进来)

然后在 vs 里就可以对 rb 进行控制了。比如说我们用 AddForce 这个方法,可以给我们的 cube 施加一个力,比如 rb.AddForce(0, 300, 500) 可以让我们的物品向前飞起来(假设 y 轴和 z 轴是朝上和朝前的)。

3.1.3 Update() 和 Time.deltaTime

我们想让物品持续移动,那么就可以考虑使用 Update,可以在 update 里给其施加一个力。因为 Update 会在每一帧渲染的时候被执行一次,因此持续移动的目的就达到了。

image.png 但是其实这个是有 bug 的,因为 Update 是每一运行一次。然而我们都知道不同的电脑,帧率是不一样的。而且就算是同一个电脑的帧率也是不稳定的。高帧率的时候,每秒 cube 受到的力更多,低帧率的时候 cube 每秒受到的力更少。
解决方案是这样的: image.png 这里的 Time.deltaTime 是个啥呢?其实它指的是上一帧渲染所经历的时间(单位为 s)。所以起到了一个平衡的作用。

粗略说:
每秒帧数 * 每一帧花的秒数 = 1  

或者准确来说,一秒种内:
第一帧花的时间 * 600 + 第二帧花的时间 * 600 + ... + 最后一帧花的时间 * 600
= (第一帧花的时间 + 第二帧花的时间 + ... + 最后一帧花的时间) * 600
= 1 * 600

因此这样每一秒内 cube 受到的力就无视帧率固定了。这也是为什么要从 3 改到 600,因为这个数字现在代表每秒钟受到的力,而不是每一帧受到的力。
也就是说,在 Update 里,将一个数乘以 Time.deltaTime,可以让这个数值代表的含义从每帧的变化,变成每秒的变化。

3.1.5 FixedUpdate()

前面的代码没有问题。但是不符合 Unity 风格。Unity 希望你在 FixedUpdate 里进行物理操作,而不是 Update 里。简单地把 Update 改成 FixedUpdate 就行。