Unity
Unity 介绍
-
什么是游戏引擎? 游戏引擎(Game Engine)是指一些已编写好的可编辑的电脑游戏系统,或者一些交互式实时图像应用程序的核心组件。这些组件提供了游戏设计者设计游戏所需的各种工具,不需要游戏设计者从零开始,可以直接引用引擎里的部分功能快速编写出游戏。
-
什么是 Unity? Unity 是由 Unity Technologies 开发的一个让你轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity2D/3D 游戏引擎可以发布到 Windows, MacOS, Linux, iOS 等诸多平台。
Unity 创作出了很多优秀的作品:明日方舟、王者荣耀、炉石传说、崩坏 3、原神、纪念碑谷。Unity 的客户包括动视暴雪,EA,Ubisoft 等国外大厂 ,也包括腾讯,网易,巨人,盛大,完美世界,西山居等国内知名大厂,全球超过 1900 万的中小企业以及个人开发者。
环境配置与安装
- Unity Hub 是一种管理工具,可用于管理所有 Unity 项目,管理 Unity Editor 及其关联组件的不同版本的安装,还可以创建新项目,以及打开现有项目。
- Unity Editor,游戏开发的主要工具,主要使用 UI 进行开发设计。
- VScode,写游戏逻辑及角色控制脚本的工具。Unity 使用的是 C# 语言,需要安装 C# 插件和 Unity 插件。
Unity 基本知识
-
Scene(场景):包含了若干 GameObject,一个游戏可以包含多个场景,不同的场景之间是独立的,并且可以通过脚本切换场景。
-
GameObject(游戏对象):一个 GameObject 就是场景中的一个对象,比如一个球,一个人;它可以独立地活动。GameObject 之间存在 Parent 和 Children 的关系,即一个对象可以从属于另一个对象,成为其子对象。注意,GameObject 之间的父子关系并非继承关系,而只是一种从属关系。
-
Material(材质):材质是用来描述物体表面外观的。它可以包含纹理、颜色等信息。材质通常与 Mesh Renderer 组件一起使用。
-
Component(组件):一个 GameObject 可以拥有若干个 Component,两者之间仍是一种从属关系。每个 Component 可以独立地实现 GameObject 需求的某些功能。常用的如 Rigid(刚体),Animator(动画)等。
-
Prefab(预设):Prefab 与 GameObject 之间的关系类似于类和对象的关系。即后者是前者的实例。Prefab 的使用能够减少不必要的重复工作。当 Prefab 被修改时,它的所有 GameObject 实例也会被修改。
-
Script(脚本):通过编写代码,并将 Script 添加为某个 GameObject 的 Component,当该 GameObject 被实例化并且处于活动状态,且该 Component 也处于活动状态时,它便可以控制 GameObject 的行为。所有需要使用 Unity 引擎的脚本,都应该继承自 MonoBehaviour 类。只有完全不依赖于 Unity 引擎进行初始化和更新,也不调用 Unity 的 API 的脚本,比如单纯进行数学计算的类,是不需要继承 MonoBehaviour 的。
-
Assets(资源):所有 Prefab, Script 以及 Material 等资源都在 Assets 中进行管理。对于规模较大的工程,总应该建立规范的目录结构。
-
工作流程:首先加载一个场景。当场景被加载时,场景中的所有 GameObject 都会被加载。当 GameObject 加载时,其所有 Component 也随之实例化。当某个 Script 实例化时,其
Awake()
方法和Start()
方法被先后调用(细节这里不说),当所有Start()
方法都被调用完毕后,游戏会进入第一帧,每隔一段时间就会Update()
一次。
快速上手——小球吃金币
完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
private Rigidbody rb;
private int count = 0;
public float moveSpeed = 0.5f;
public Text countText;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
countText.text = "Count: 0";
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
rb.AddForce(new Vector3(x, 0, y) * moveSpeed);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("CoinTag"))
{
other.gameObject.SetActive(false);
count++;
countText.text = "Count: " + count.ToString();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoinRotate : MonoBehaviour
{
// Update is called once per frame
void Update()
{
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
// Start is called before the first frame update
void Start()
{
offset = transform.position - player.transform.position;
}
// Update is called once per frame
void Update()
{
transform.position = player.transform.position + offset;
}
}
编辑器操作
我们进来可以看到大概分为四个窗口。如果你进来的这个窗口布局跟我的不一样,你可以点击右边的这个下拉,然后选择 default。Unity 还给我们提供了一些其他的窗口布局,你可以挨个点看一下。先介绍一下中间的这个窗口,这个是我们的游戏场景窗口。在这里面就是我们的游戏三维世界。我们可以在这里创造我们的游戏场景,摆放我们的游戏物品。然后最后游戏运行的时候,我们就是在这样一个世界中去游玩它。这个场景目前现在什么都没有用,那些默认给我们创建了两个物体,一个是我们的摄像机,摄像机就是我们游戏中的视角,也就是说我们的眼睛,我们通过游戏中看到的物品都是通过摄像机来看到的。这边这个太阳就是我们游戏中的光照,比如说你光照的颜色,比如说是早上、中午还是晚上,都是通过这个来调节的。
我们先选择我们的摄像机,在右边的窗口可以看到摄像机的详细属性。这边包括了这个物品所有的属性和它的行为,行为你可以添加一些新的行为,这个我们等一下再来说,我们先来看一下这个属性有哪些。比如说它的 position 就是它的位置,那我修改它的一个位置,修改成 5,你可以看到这个摄像机跑到了这边来了。再修改一个 10,可以看到它跑到上面去了。我们再来设置一下 rotation,就是摄像机的角度。这个地方我不用数字来设了,我把鼠标放到这个 X 轴上面进行拖动,可以看到我们摄像机的视角是有一个旋转的,能够让我们看到不同的这样一个视角。
还包括一些摄像机的行为。比如说目前这个摄像机其实是什么都没有的,我们可以运行一下这个游戏,看一下我们点击这个上面的三角运行一下这个游戏。好,我们这是你可以看到我们跳到这个 game 窗口了。前一个窗口就是我们的场景设计窗口,game 窗口就是我们实际游玩的窗口。在这个窗口我们可以看到我们的游戏其实也是已经运行了。但是我们游戏场景中,现在是什么的物体都没有,而且我们这个摄像机也是什么行为都没有,所以我感受不到这个游戏其实是在运行的。
这时候我停止运行,给我们的摄像机添加一个重力的行为。我点击这边的 add component 添加组件。我们点击 rigidbody 添加我们 3D 的这样刚体组件。这时候我们的这个摄像机已经有了一个重力了,这时候我们继续运行这个游戏。可以看到画面其实是没什么区别的。但是我们点击这个 scene 窗口,可以看到我们的摄像机在不断的往下沉。
除了添加 unity 给我们写好的一些组件,我们还可以添加一些 C# 脚本。我们自己定义的一些行为,比如说旋转这个摄像机,或者是摄像机跟踪某一个目标,都是可以通过脚本来完成的。
这时候你可以看到我现在移动窗口,我不知道我的摄像机在什么区域了,而且我也不知道我场景中到底有哪些物体。我们可以看一下左边的这个窗口,这就是我们场景中物体的列表。你比如说你看这里给我们列出来一个 light 光照,给我们列出来一个 camera 相机,我双击这个物体,它就给我们聚焦到这个上面来了。
下面我们来介绍一下这个资源窗口。资源窗口准确来说其实就是我们的项目文件夹。我们可以在这里面添加一些图片,把图片添加到这里面来,或者添加一些脚本都可以。我们可以打开它所在的文件夹,这样我们就能看到了。你看这个里面现在有是我们这就是我们项目所创建的所有的文件。
场景窗口介绍
此时我们来看一下如何在场景中进行漫游。鼠标右键继续按着不松,然后按住键盘的WASD键,就W是前进,S是后退。然后A键是左边,D键是右边。配合我们鼠标的旋转,可以做到像这样,这个你们稍微自己试一下。然后还有两个键,一个是Q键,一个是向下,一个是E键,一个是向上。这些操作都是在鼠标按住右键的前提下才能进行这样的操作。如果不按右键的话,我们键盘上面的键会有一些其他的效果。这个我们马上来说。
下面我们来对场景中这个模型的编辑。现在还没有模型,unity给我们提供了一些简单的基础模型,我们用这个来做示例,先点击左上角这个加号,然后有一个3d object,里面会是里面是unity给我们提供了一些简单的基础模型,我们可以创建一下,看一下。比如说cube是一个正方体立方体,然后索菲亚球体。后面的我不创建了,我先来就用这个cube来给演示一下如何编辑游戏中的场景,按住delete把它删掉。好,首先就是选择我们unity,选择一个物体,直接点击它就可以选择,或者是一个范围的选择。
我们来看如何编辑物体。首先选择我们的立方体,可以看到立方体上面出现了一个三维的一个坐标轴。如果你的跟我的不一样,你没有出现坐标轴,那么你就点击左上角这样一个上下左右的一个图标。可能如果你比如说默认的话是这个小手的图标,那就就像现在这样变成了这样一个小手,它只能拖动场景,但是他没有办法像刚才那样选择。展示这个物体的三维坐标。好,我们再回到这个按键,展示这个坐标。Unity这个坐标跟我们数学中的这个坐标有一点不一样。它是以Y轴向上,绿色的这个代表是Y轴,然后X轴代表的是红色的是X轴,然后Z轴就是这个蓝色的。
好,我们刚才也看到了,我们挨个点击这个轴的话,是可以进行在这个轴上的一个移动的。比如说X轴、Z轴、Y轴,这个是移动工具。
下一个工具就是鼠标继续点到左上角这个,这是一个旋转工具,比如说它也是对应了每个轴的旋转。比如说我沿X轴旋转多少度,沿Z轴怎么旋转,这些都是比如说达到了一个这样的一个状态,这就是我们的旋转,可以看一下。按住control,最后把它撤销掉,再回到最开始的状态。好,继续看下一个工具。
下一个工具是这个缩放。缩放就是使我们的模型变大变小,也可以沿着轴缩放沿着轴缩放或者沿着整体缩放。它中间这个白色的点就是统一缩放,每个轴都会按照一定的比例来缩放。
下面也是关于缩放的一个工具。但是这个工具是按照面来缩放的。你比如说点击这边一个小框的一个图标,它它会展示这样一个面。你看1234这样一个面,这个面是以你观察的角度来的。你比如说我往这边来一点点,你看它这个面就变成这样的一个面。这个面是我们可以进行缩放的,比如说这样的缩放或者是这样的缩放。这也是一个缩放的一个工具。
另外一个工具是一个整合工具,它里面就是左边点击这样一个复杂稍微复杂一点的图标,它是一个整合工具。它既包含了移动旋转,也包含了缩放。但是它这个缩放在我这里只能不能按照单轴缩放,只能全部缩放。你比如说移动没问题,旋转也没问题。然后缩放要点这白色这个点,有这样一个缩放,这只能整体的,不能按照单轴缩放。
你看这里面会有每个面的一个区域,比如说YY轴的这个绿色的区域,就是按照X和Z轴进行这样一个平移的一个移动。这个在我们刚才移动工具里面也有。你看我切换到这里面,切换到这个上下左右的图标,在我们的移动工具里面也有,就是按照某一个面进行移动。比如说如果按照Z这样一个面进行移动。好,这个缩放工具编辑工具就已经讲完了。
除了除了在这上面点击这些图标以外,我们还可以按住键盘中的快捷键。首先我们第一个快捷键是,比如说我切换到小手,第一个快捷键选中一下这个物体,第一个快捷键就是我们的W按住W键直接就可以进行物体的移动,展示坐标轴。然后按住物体的一键就是我们的旋转,按住R键就是我们的缩放,按住T键就是我们的面面缩放,然后按住Y键就是我们的综合工具。还有就是我们上一节不是介绍了这个属性窗口,在这一节中属性窗口也可以进行对它进行相应的操作。比如说依然选中这个物体,然后右边这个窗口展示了这个transform这个属性下面会有我们的position位置,rotation它的旋转,还有scale它的缩放。
你比如说位置,我把它摆到一个五的位置,Y轴向上提两个像素,两个单位,然后Z轴往前去5单位,或者这样的话它这个控制更精细。你向你移动的话,相对来说就没有那么精细。你看左边这边我移动了一点点,左边这边它可能会有一些小数点什么的。就是你希望得到一些更好的效果的话,可以直接从右边这个属性窗口进行设置。那旋转角度也是我X轴旋转45度。Y轴旋转45度,Z轴也旋转45度,相对来说就比你手动控制的更精细一点。
除了这样,这个编辑器右边窗口还会有一个小操作。就是说你把你看你把鼠标放在X轴上的时候,它会变成一个左右拖动这样一个图标。你直接按住鼠标左键,然后直接进行左右拖动,都是可以的。
最后一个功能就是说一下聚焦。比如说你不知道跑到场景中的一个什么样的位置,这时候你选中物体或者在这边选中物体,按住我们的F键就可以瞬间走到我们当前这个物体的。
材质创建
这时候我们需要创建材质,我们可以创建一个材质的文件夹,我们叫做materials。好。有了这样一个文件夹之后,我们就需要创建我们的材质了。
我们先给我们的地面创建一个材质,首先在这里面右键。选择create,然后选择material材质。在这里面我们把它设置给它一个颜色。我们的地面我希望颜色是灰一点,灰灰的。这个随便晒一下。地面有一个光滑度,我们的地面肯定是不光滑的。然后这个是金属金属质感的话,地面肯定也不需要什么金属质感。
创建了好这样一个地面之后,我们给它拖到这个地方。好,这样就是直接把材质拖过来,拖过来给他就可以了,那直接拖过来就可以了。你也可以点击我们这个地面,然后这边可以看到这是我们刚才拖进来的这个材质。
下面我们要创建我们的墙的这样一个材质,我们四周围墙的这样一个材质。来,首先是我们的。墙的这样一个材质跟地面差不多,我们光滑度给个0.25,石头有一点也其实也不光滑,然后颜色我们取一个。取一个稍微黑一点的颜色,然后把它拖到这个墙这个地方,那四个围墙都给他拖一下。好,这样我们墙也创建好了。
下面我们来创建我们主角的这样一个材质。继续创建 material。给一个蓝蓝的颜色吧。 那我们来演示一下这个金属质感是干嘛的。首先这是粗糙,这样看就感觉像是一个橡皮的那种橡皮泥的那种球。然后我把它改成光滑一点,可以看到它变得就跟镜子一样。然后上面这个金属也是你是金属或者不是金属,调到一个你满意的一个这样的一个字,让它看起来稍微像是一点金属。我看改0.75。这样看我们的小球还可以。好,这是简单的材质。
材质其实还可以有更多的玩法,现在只是一个简单的设置了基础颜色,设置了它的金属度,设置了它的光滑度,然后还有一些其他的,比如说我们还可以设置一些贴图纹理贴图,让它让这个材质看起来像是岩石,像是水面,这些都可以通过材质来完成。材质主要就是定义我们的长相,我们比如说我们场景中物体的长相一般都是由材质来定义的。我们的模型给一个大概的模型,然后材质赋予它不同的材质,让它展现不一样的样子。比如说同样都是一块都是一个cube,他有的是可以变成为镜子或者是石头,都可以通过材质来弄,或者通过我们的那个shader,shader也可以达到这样的目的。
C# 脚本
这里默认给我们引入了unity engine的这样一个命名空间。这个命名空间下面有一个mono behavior这样一个类。然后我们继承这个类,就可以使用这个类下面的start的方法和update方法。这个类下面其实还有一些其他的方法,我们后面再来说,先来介绍一下这个start方法。
Start的方法就是当游戏开始运行的时候就会执行的一个方法。我们在这里面可以进行一些数据的初始化。比如说你枪的一些子弹,比如说30发,你在这里可以初始一下它的数值,或者初始一下我们场景中物体的位置。比如说我场景中的物体原来是在这个位置,我希望游戏开始的时候,他继续回到这个0.50的位置。我也可以在这个脚本初始化里面去初始化这个,就是初始化我们脚本,初初用代码去初始化我们的模型的一个位置。
重点我们来说一下这个update的方法。Update的方法代表的是什么意思呢?就是我们游戏每一帧都会执行的一个方法,就是我们游戏的。
我们这里来介绍一下游戏的一个概念,叫做FPS。FPS的意思就是游戏在每一秒钟向屏幕输出的画面的一个数量。比如说FPS等于30。就代表每一秒钟向屏幕输出30张画面。那么我们这个update的方法就会执行30遍。如果你的FPS是120,那么这个update就会执行120次。这个随着比如说你游戏场景比较复杂,那么你FPS可能会低一点,那么这个方法就会执行的少一点。但是每一针反正就是都会执行这样一个方法。
C# 移动脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
private Rigidbody rb;
public float moveSpeed = 0.5f;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
rb.AddForce(new Vector3(x, 0, y) * moveSpeed * Time.deltaTime);
}
}
金币制作
好,我们回到这个materials,这个材质这个管理里面,我们添加一个。添加一个material。这我们给它设置一下它的颜色。设置成稍微偏黄一点的颜色。稍微亮一点,然后这个金属度。也可以来一点,光滑度也可以来一点,不光稍微光滑一点,然后金属度来一点,这样看起来就挺像一个金币的。这个你们随便设置,好像也有一点点丑。看有没有再亮一点的颜色,再亮的颜色稍微再亮一点。
运行的时候我们我们是这样的,现在我们运行的时候,金币是不动的,我们小球碰到他也没什么用,就会被它弹住。被他弹住是因为我们和他之间都有一个叫做cleaner。Cleaner就是我们绿色的线条包围的这个部分,就是我们小球的一个碰撞区域。你看这个地方它也有是这个绿色的,因为我们给的是黄色,所以这个绿色你看这个绿色就是它的一个碰撞区域。如果我们两个都有碰撞区域的话,就会像刚才这样,我们碰到它之后,就会被它弹开,就会两个就会撞在一起,并不会重合。
现在我希望是什么情况呢?我希望我的小球在游戏运行的时候,是能够一直在旋转。这样我们怎么让它旋转呢?那自然就是加入一个脚本,然后在在这个脚本里面,我们去每一帧对它进行一个角度的调节。
我们继续回到我们这个我们我们直接点击,直接点击这个。点击这个物体,点击这个金币,然后点击add component,添加一个脚本。这时候我们现在要怎么做?我们现在我们不需要这个start,我们直接更新这个帧率就可以了。我们现在要做的操作是什么?我们现在要做的操作就是获取到这个物体,然后给它旋转。这个地方我们就不用regard body这个地方,因为是这样的,因为我们不需要让小球受到力,我们只需要改变它的角度就可以了。
这时候我们如果想建第二个金币,我们有几种方法。我们可以再拖一个Q,再拖一个Q,再重新设置一下它的属性,然后把这个脚本再复制给这个cube,这样它也会得到一样的效果,或者我们直接复制选择这个cube。按住control加D,按住W键,一个再到这边,两个可以看到运行一下,可以看到三个东西都可以用了。现在我们还有一个方法,还有一个方法是这个方法是比较一劳永逸的。就是当你做好了一个组件之后,你希望在任何地方使用这个组件。那么unity给你提供了一个什么东西?给你提供了一个叫做预制体prefab这样一个东西。
Prefer是怎么用呢?你比如说我现在这个东西已经制作好了,它的脚本也有了,我们直接把这样一个cube拉到这个里面来。好,可以看到这个cube已经变蓝了,它已经变成一个prefab了。你点这边的话可以聚焦到这个上面,我们点击返回,你把它给删掉。这时候它就相当于是一个写好的一个组件。
这时候我希望在哪里用到这个组件,好,直接拖出来往上来一点。继续直接拖出来,这样我们也可以把这个组件导出去,在其他项目也可以用,或者新建一个场景都可以。
实现吃金币
在unity的脚本中,我们回到我们的scripts,打开我们的player。在unity脚本中给我们提供了这样一个的碰撞的一个需求。我们点击小球,我们在小球的这个脚本里面打开一下,它edit的小球的这个脚本里面调用这个方法叫做void叫安。我看一下,不不是这个方法,不是这个方法。叫做触发。也就是说我们两个物体,两个碰撞体碰撞之后会有一个触发事件,叫做。
Wait on trigger, 这个就是我们当前这个小球,我们这个脚本是在小球上面,当前这个小球碰撞的一个cleaner。比如说我们的小球碰撞到这个金币了,碰撞的那它这个box cloud就是这里就是我们这个box cleaner。Box cleaner可以获得我们这个小球的本体,然后对它进行一个隐藏。这个地方我们先来写一下写一下这个代码。你看我们这个other点game object获取到这个game object,然后它有一个set active设置,我们的可用状态是false。这样就可以直接把我们的这个金币进行一个隐藏。
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("CoinTag"))
{
other.gameObject.SetActive(false);
count++;
countText.text = "Count: " + count.ToString();
}
}
就比如说你看我是在小球的这个代码里面调用on trigger的,那么代表的是什么意思呢?代表的是我们小球如果与某一个物体发生了碰撞,那么这个物体就是这个other other other,我们可以通过other的这个game object获取到这个物体,获取到这样一个物体game object,就可以直接对它进行一个可用属性的一个设置,设置成false它就不可见了。好,我们下面来运行一下。可以看到并没有什么效果,我们碰到它之后还是跟上面的那个情节一样,依然是这样的。我把这点这个速度调快一点,这个速度调慢了,感觉操作有点不好操作,还是设置成一。可以看到我们碰到这个小球没有任何的效果。
这里就要说明一下,这个on trig into。需要一个前置条件,需要一个什么前置条件呢?就是我们被碰撞的物体一定要是一个trig,也就是说它的box cloud要设置成一个,你看设置成一个推广。你看可以看到我们这个小球已经消失了,但是其他的我们看一下,其他的我喷上去还是没什么效果。
没什么效果的原因也是在这里,它不是一个垂直,也就是说我要把所有的物体都设置这一个推杆,这就很麻烦。那刚才我们这里已经改过它了,我们可以想到刚才我们是制作了一个预制体,就是prev,也就是说它们这些物体都是来自于这个prefect。所以我只要修改,我选一下选一下我们的profile,选修改我们prefer里面的its trig,就可以看到你看它也变成了一次tag,它也变成了一个trig。也就是说只要我修改了prefab里面的,他们就全部都变了。然后这个时候有一个不会变,就是它不会变,因为我们已经手动修改过它了。你看它前面有一个蓝色的这样一个区域,代表这个属性是我们修改的,我们给它撤销一下。可以看到现在他也被变回去了。
这点说可能有点没什么说服力,我重新来一遍,我们先点击这个prefab。点击这个its trigger,可以看到它的its trigger也没有了,他的一个trig也没有了。好,现在我来点击一下它,给它设置一个一字trig。好,你可以看到它前面有一个蓝色的这样一个标注,就是告诉我们这个prefab已经被我们修改了。然后此时我把它的一个黑口给它取消掉。
你看现在他们都没有1 trig,我继续改到我的prefab里面,把它设置一trig,可以看到它的its trig已经设置好了,它也已经设置好了。但是,唯独就他是没有设置的。因为这样一个属性,是已经被我们修改过的,所以我们修改prefab,并不会云,不并不会影响它。所以这时候,我们只需要撤回一下,可以看到,它也被设置了一个椅子吹个好,下面我们运行一下,可以看到我们只要经过这个地方都被它吃掉了。
我们吃金币的这个动作也已经做完了。主要用到的是什么?主要用到的就是一个on trigger into触发器。如果我们触发了其他的一个碰撞和,我们就把这个碰撞盒里面的这个game of jack给它设置成隐藏就OK了。
相机调整
如果你觉得这种方式比较麻烦,我们还可以以一种更加快捷的一个方式。就比如说我现在在场景中漫游的时候,我看中的是这样一个角度。那么我怎么让我们的摄像机直接跟随我现在这样一个角度呢?让摄像机到我当前的位置,以我当前的视角,我们只需要按住一个组合键,在键盘上按住control加shift,然后加F键按一下。好,可以看到我们摄像机已经消失了。我往后退一点,可以看到摄像机就在我刚才这个位置。这个快捷键必须要选中摄像机,如果我不选中摄像机的话,按这个快捷键是没有用的。
相机跟随
但是这样会带来一个什么样的一个后果呢?这样带来的一个最直观的后果就是我不光位置进行移动,你跟随移动我的角度进行移动,你也会跟随移动。我们可以运行一下游戏,看一下这个效果。你看我往前运动,可以看到小球的角度也在被迫的进行运动,这个有点运用就不展示了。所以这种方式肯定是不适合。
这里我们小球怎么去获取呢?小球获取我们在这里有一个表示方法之前,我们选择我们的小球之前,我们小球是不是暴露出来过一个属性,暴露出来过一个速度,我们可以直接修改它的速度。那么我刚才给摄像机的这个脚本,我是不是也可以暴露出来一个属性,暴露出来一个专门用来接收物体的这样一个属性。这样我直接把我们的小球复制过去是不是就可以了。
我们在unity中有这样一种方式。首先我们要想获取场景接收,就是接收用一个属性接收场景中的这样一个这些模型,我们可以用什么类型呢?我们可以public,public代表的就是往外暴露,public叫做game object。我们给它起个名字,就是我们的小球player。
我们先把这个注释掉,然后我们回到我们的原理题编辑器。点击我们的这个camera,可以看到这时候我们的脚本暴露出来了一个属性,这个属性可以接收。为什么可以接收?类型为game object,也就是说我们场景中的模型的。这时候我们想把小球给它传进去,我们直接拖住这个小球,先点一下这个项目,直接拖住这个小球到这个地方。这样我们回到脚本。我们这个player就可以获取到我们现在的小球的这样一个模型了。
UI 界面
我们吃到小球之后,我希望在左上角的这个位置显示一下我们当前吃掉的一个数量。点击这边的加号,选择 UI,选择一个 text。我们可以聚焦一下这个 text 的上面,或者我们先聚焦到 canvas,选择这个canvas,然后鼠标拿到这边,然后按住 F 可以看到这个比较大。我们可以设置一下当前这个界面的一个布局方式,设置它的锚点,当前是在中间这个位置,我们两个都移动到顶部。
现在我们给这个文本设置一下其他的一个东西,比如说我们把它的字体设置成 26,然后我们的位置往往到边上去一点点。可以看到这边已经显示了它这样一个操作了,然后还能设置什么?应该还能设置它的颜色,对齐。
上下设置一个对齐方式,上下设置一个对齐,那这个地方还可以往左边去一点,好看一下。有点太靠边了,我们还是靠边,不让他那边对齐了。可以,这边这个效果还可以,应该还可以。
设置它的颜色,你看color我们设置一个白色,白色相对来说比较显眼。白色设置好,运行好,这边设置了一个白色,下面我们怎么办?下面也就是说我们这个地方我们就不管它了,运行的时候就是对的。然后 unity 显示UI的这个方式,就是在我们先聚焦到这个小球上面去。显示UI就是这么显示了一大块。但是你实际运行的时候,它会根据你的屏幕进行一个适当的一个缩放,正好摆放到你的屏幕上面去。
下面我们打开小球的一个脚本,小球的脚本我们刚才在这里面,只要小球和这些物体相互触发,是不是就会把物体设置成隐藏?那么当它设置成隐藏之后,我们就给小球来一个计数。然后把这个计数再显示到我们的这个文本上面,是不是就可以了?
我们先来设置一下技术,我们定一个变量到上面定一个到上面定统一定一下。的private int我们的count。Count等于多少?最开始肯定是零,因为我一个都没吃。看它等于零到这里面怎么办?看它是不是就加加了,看到就加加了,然后到时候我们把这个数值再显示一下,或者就是更新界面的。组件为当前的count值。
那我们界面的组件我们怎么获取到呢?可以看到我们其实可以干什么,可以和man camera一样,我们继续暴露一个组件的属性出来。我们继续暴露一个属性出来,把这个text复制给这个属性是不是就可以了。那么我们现在试一下,点击小球,它的脚本在这儿,这里现在只暴露一个我们可以设置的一个速度。
现在我们打开我们的脚本,我们继续给它暴露出一个属性,这个属性我们要暴露成什么?这个属性我们要暴露成它的类型?这个地方要说一下public它叫什么?它叫text的类型,对吧?这个text的类型在什么地方呢?在unity engine的UI下面,这里引用了一个unity engine的一个UI它叫什么text呢?就叫我们的count text。
这样一个属性已经暴露完成了。我们来看一下,回到unit等待一下,点击我们的小球,可以看到这样的属性已经在这个地方了,现在它还没有值。我们把什么我们把这个text直接拖给他。
那下面我们要做的就是什么?我们在这里面是不是就可以获取到这个text的组件了?可以获取到它的组件,那就证明我可以更改它里面的内容。
人物与动画初探
using System.Collections.Generic;
using UnityEngine;
public class AnimatorTest : MonoBehaviour
{
private Animator animator;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if(Input.GetMouseButtonDown(0))
{
animator.Play("left");
}
}
}