这是 Unity 基础系列教程的第一篇博客。我们将由浅入深,一步一步学习Unity及游戏开发相关的东西。整个系列教程所使用的Unity版本为 2018.4 及以上就可以,如果要使用特殊版本,则会在文中指出。
今天要做的是一个能够实时显示当前时间的时钟,就是下面这个东东。
1 首先建立一个新工程
首先打开Unity,创建一个新工程,名字自己定,例如 Clock 就可以。默认打开后,Unity 默认布局是下面图的样子。
你也可以更新布局,例如换成同时显示View和Game视图的布局,只需要点击编辑器最右上角的那个按钮,然后选择 2 by 3 即可成为下面图的样子。
下面是分辨率的设置,一般游戏开发中,会使用一个基准分辨率,很多游戏采用的是 16:9 的模式。这个在 Game 视图中设置,看下面的图,选择 16:9 即可
1.1 创建一个 GameObject
默认的场景中,会包含两个 GameObject,一个是主相机 MainCamera, 一个是灯光 Directional Light。这两个东西保持默认就好,现在我们创建一个新的物体,在 Hierarchy 面板右键,然后 Create Empty,或者通过菜单栏 GameObject/Create Empty都可以,这样就会在Hierarchy 面板上看到我们新建的物体,然后对这个物体重命名为 Clock,并且把它的位置置为 (0,0,0)。看下面的图
1.2 创建时钟的表盘
创建表盘,我们使用 Unity 默认的物体 Cylinder,然后改变它的大小,使其成为我们的表盘。首先,通过右键 Hierarchy 空白处,或者通过菜单栏 GameObject 中的 3D Object/Cylinder 选项,来创建一个 Cylinder,就是一个圆柱体。
Cylinder 默认已经有了很多组件,Mesh Filter、Capsule Collider、MeshRenderer。默认我们不需要物理模拟方面的东西,所以我们先把 Capsule Collider 这个碰撞器给删掉,通过右键这个组件,Remove Component 即可。
然后我们改变园柱体的大小,因为表盘是一个圆盘形状的东西,所以我们把圆柱体压平,也就是改变y轴的大小始可。把圆柱体 Scale 设置为 (10, 0.1, 10),如下图。
接下来要做的,就是把 Cylinder 重命名为 Face,然后把这个物体拖到我们一开始建立的 Clock 物体下面,作为它的子物体,并且把坐标归为 (0, 0, 0),如下图。
1.3 创建时钟刻度
表盘是 360 度,有 12 个小时,所以每个小时间隔的角度是 356 / 12 = 30 度。也就是说,我们需要每隔 30 度创建一个小时刻度。最终效果如下
接下来我们一步一步来创建刻度。
首先创建一个 Cube,将它的 Scale 设置为 (0.5, 0.2, 1),然后设置它的位置为 (0, 0.2, 4)。如果没错的话,它现在应该处于 12 点位置。
但是有一个问题,因为它默认是白色的,看不清,所以我们创建一个材质,命名为 Clock Dark,然后设置 Albedo 颜色值为 (73 73 73 255),然后把这个材质拖到Cube上,现在应该是下图中的样子。
接下来我们继续创建其他刻度,但是有一个问题,我们怎样才能精确地设置每一个刻度的位置呢?其实很简单,只需要旋转30度即可,但是,不是旋转刻度本身,而是要建立一个新的 GameObject。
新建一个新的空 GameObject,坐标置为 (0, 0, 0),然后将刚才创建的 Cube 拖动到新建立的 GameObject 下面,作为子物体,将 Cube 重命名为 Hour Indicator。如下图这样
下面我们创建 1 点时的刻度,只需要复制上面的 “GameObject”,注意,不是复制 Hour Indicator,而是复制它的父物体,然后将复制后的物体 y 轴旋转 30 度即可。那 2 点的位置,就是再复制一个 GameObject,这只旋转为 60 度即可。其他的时间刻度也同样,只需要依次增加旋转角度。
当所有刻度创建完毕后,我们将所有的 Hour Indicator 拖动到之前创建的 Clock 下面,然后删除掉为了旋转而临时创建的 “GameObject”,到此,刻度创建完毕。如下图
1.4 创建时钟指针
创建指针,与上面创建刻度类似。首先新建一个 Cube,命名为 Arm,设置 Scale 为 (0.3, 0.2, 2.5),设置坐标 (0, 0.2, 0.75)。然后将上面创建的材质 Clock Drak 也赋予我们刚建立的 Arm。现在状态如下
为了后面旋转,我们还要创建一个空的GameObject,命名为 Hours Arm,然后将 Hours Arm 坐标设置为 (0, 0, 0)。然后将之前创建的 Arm 拖动到 Hours Arm 下面,作为其子物体。然后再将 Hours Arm 拖动到 Clock 下面。现在的层级如下
接下来我们再创建分针和秒针,和上面创建时针基本类似。选中之前创建的 Hours Arm,然后按 Ctrl+D (如果是Mac,则是Command + D) 两次,复制两份 Hours Arm,重命名为 Minutes Arm 和 Seconds Arm,作为分针和秒针。
设置 Minutes Arm 下面的 Arm 缩放和坐标,Scale 为 (0.2, 0.15, 4),Position 为 (0, 0.375, 1)
设置 Seconds Arm 下面的 Arm 绽放和坐标,Scale 为 (0.1, 0.1, 5),Position 为 (0, 0.5, 1.25)
为了使秒针更明显,我们创建一个新的材质,命名为 Clock Red,然后设置颜色值为 (197, 0, 0, 255),然后将材质拖到 Seconds Arm 下面的 Arm 物体上。目前应该是下面的样子
2 实时显示当前时间
接下来就是写代码的时间,我们先看代码,然后对代码作解释。代码中我们实现了两种指针行走的方式,一种是逐步方式,一步是持续方式。注意看代码中的注释
using UnityEngine;
using System;
public class Clock : MonoBehaviour
{
// 定义时针、分针、秒针步伐角度
const float degreesPerHour = 30f;
const float degreesPerMinute = 6f;
const float degreesPerSecond = 6f;
// 时针、分针、秒针的旋转体 Transform
public Transform hoursTransform;
public Transform minutesTransform;
public Transform secondsTransform;
// 指针行走模式
public bool continuous = false;
private void Awake()
{
UpdateDiscrete();
}
private void Update()
{
if (continuous)
{
UpdateContinuous();
}
else
{
UpdateDiscrete();
}
}
// 逐步方式更新当前时间
private void UpdateDiscrete()
{
DateTime time = DateTime.Now;
hoursTransform.localRotation =
Quaternion.Euler(0f, time.Hour * degreesPerHour, 0f);
minutesTransform.localRotation =
Quaternion.Euler(0f, time.Minute * degreesPerMinute, 0f);
secondsTransform.localRotation =
Quaternion.Euler(0f, time.Second * degreesPerSecond, 0f);
}
// 持续方式更新当前时间
private void UpdateContinuous()
{
TimeSpan time = DateTime.Now.TimeOfDay;
hoursTransform.localRotation =
Quaternion.Euler(0f, (float)time.TotalHours * degreesPerHour, 0f);
minutesTransform.localRotation =
Quaternion.Euler(0f, (float)time.TotalMinutes * degreesPerMinute, 0f);
secondsTransform.localRotation =
Quaternion.Euler(0f, (float)time.TotalSeconds * degreesPerSecond, 0f);
}
}
上面代码中,首先我们定义了各指针每一步行走的角度,然后定义了三个变量,用于引用三个指针旋转体的Transform,最后写了两种方式的更新指针位置,通过 continuous 变量控制使用哪种方式更新指针。
将脚本拖动到我们之前建立的 Clock 物体上面,然后将三个指针的旋转体 Transform 拖到脚本对应的变量区域,如下图所示
接下来,运行即可看到效果
下面是未勾选 continuous 的运行效果
下面是勾选了 continuous 的运行效果
好了,这次的教程到这里就结束了,如果有什么问题,欢迎在下面留言~
原文翻译自 Game Objects and Scripts Creating a Clock Github 代码下载: animating-the-clock.unitypackage