基礎1——遊戲物體和腳本——造一個鍾

首先是匯總地址

雪之下雪乃:純文字和圖片的Unity教程-系列概述和匯總zhuanlan.zhihu.com圖標

本節將會涉及到:

  1. 用最基礎的遊戲物體造一個鍾
  2. 寫C#腳本
  3. 讓鍾旋轉起來以顯示時間
  4. 控制鐘的指針

這是本教程的第一篇,將會使用Unity自帶的最基本的遊戲物體和腳本來創建一個顯示實時時間的鐘。

我使用的Unity版本為2017.2,最好與我的版本保持一致或接近我的版本。

1建造一個簡單的鐘

1.1創建遊戲物體

打開Unity,調整到你適合的界面狀態

創建空物體,改名為Clock,把它放到原點,大小設為1。

在Unity中,改變父物體的Transform參數會影響子物體。

整個鐘都會作為Clock的子物體存在,所以確保Transform參數如下。

1.2創建鐘的表面

創建一個cylinder,它自帶以下組件

Mesh Filter:有一個對內置Cylinder網格的引用

Capsule Collider:碰撞器用於物理檢測。Unity沒有現成的Cylinder Collider,所以是Capsule Collider,這裡不會用到,所以可以remove。

Mesh Renderer:這個組件確保物體的網格得到渲染。同時控制渲染的材質,這裡用的是創建3D物體的默認材質

調整其Transform參數如下

將它改名Face,並放到Clock下面

1.3創建鐘的時盤

鐘有12個表示小時的指示(Indicator),我們用Cube來製作

創建Cube,參數設為如下

現在Cube和Face的材質一樣,所以很難分別,我們為時盤單獨創建一個材質

Albedo是一個拉丁單詞,簡單講就是材質的顏色

接著給時盤使用這個材質

把Cube的名字改為Hour Indicator。

現在這個是12點的時盤,如何創造12個來表示12個小時呢?這裡有個技巧。

因為子物體的Transform會隨著父物體的Transform變動,所以創建一個臨時空無體作為父物體,記住父物體必須在原點!

再把臨時創建的GameObject複製11個,每個繞y軸旋轉依次增加30°。把Rotation的y值為別設為:30 60 90 120 ........ 12 * 30 = 360,時盤就做好啦

最後把所有的Hour Indicator放在Clock下面,刪掉臨時創建的父物體,調整層級結構如下

如果你看到有的值是90.00001,不用擔心,因為這些值的類型是浮點型,只要不影響視覺效果就不用擔心。

1.4創建鐘的針

首先是時針,創建Cube改名Arm,調整參數如下,使用Dark材質

我們會創建三個空物體分別作為時針,分針和秒針的父物體。

把時針放在一個空物體Hours Arm下面,記得空物體要放在原點,因為我們的針是繞著原點轉的。

接著是分針和秒針,把它們的Arm參數改為如下

分針position(0, 0.375, 1),scale(0.2, 0.15, 4)

秒針position(0, 0.5, 1.25),scale(0.1, 0.1, 5)

給秒針創建一個新的紅色材質,更加醒目

做好就是這樣啦

2讓鍾跑起來!

2.1組件類型

創建一個C#腳本,掛在Clock遊戲物體上。

Unity只能使用MonoBehaviour的子類來作為組件,所以要掛在遊戲物體上作為組件的腳本,一定要繼承MonoBehaviour。

2.2Hold住Arm

訪問修飾符是public就可以在inspector面板中看到,這裡採用拖拽賦值,把Scene中的遊戲物體直接拖到Inspector的相應位置

public Transform hoursTransform;

2.3Hold住三個Arms

同樣地把分針和秒針也加進來

public Transform hoursTransform; public Transform minutesTransform; public Transform secondsTransform;

也可以寫成這樣:

public Transform hoursTransform, minutesTransform, secondsTransform;

最後給這三個欄位賦值:

2.4獲取時間

DateTime 結構體在System名稱空間下,這不是一個Unity的類型,而是屬於.NET

using System;using UnityEngine;public class Clock : MonoBehaviour { public Transform hoursTransform, minutesTransform, secondsTransform; void Awake () { Debug.Log(DateTime.Now); }}

2.5讓針轉起來

Quaternion.Euler這個方法將XYZ軸的正交角度轉換成四元數

四元數建立在複數的基礎上,用來表示3D旋轉。雖然四元數比三維向量更難理解,但是也有很多有用的特性。

在Unity中,Quaternion是一個結構體.

const float degreesPerHour = 30f, //12個小時是360°,所以一個小時就是30° degreesPerMinute = 6f, //同理每分鐘和每秒都是6° degreesPerSecond = 6f;public Transform hoursTransform, minutesTransform, secondsTransform;void Awake () { hoursTransform.localRotation = Quaternion.Euler(0f, DateTime.Now.Hour * degreesPerHour, 0f); minutesTransform.localRotation = Quaternion.Euler(0f, DateTime.Now.Minute * degreesPerMinute, 0f); secondsTransform.localRotation = Quaternion.Euler(0f, DateTime.Now.Second * degreesPerSecond, 0f);}

輸入以上代碼開始運行,則可以看到一開始時,時鐘會顯示當前的時間。但時鐘並不會轉動,因為Awake只會在開始時被調用一次

2.6真正讓針轉起來

Update會每幀調用一次。我們把以上Awake的代碼放到Update中,並且用time變數保存DateTime.Now,更加簡潔

void Update () { 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); }

2.7連續旋轉

我們的鐘已經轉起來了,但是是離散的,這跟DateTime.Now返回的數值有關。現在我們讓鍾連續轉動。

加一個布爾變數來控制是否是連續轉動

public bool continuous;

可以在Inspector面板上看到

把原來在Update中的代碼放在UpdateDiscrete方法中,另外加一個UpdateContinuous方法。

TimeOfDay會返回一個TimeSpan類型的值,其中包含TotalHours, TotalMinutes, and TotalSeconds.

Unity只用單精度浮點,所以在用之前強轉一下

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); }

把連續和不連續的分開,我們可以在Inspector中控制continuous的值來選擇調用哪個方法

void Update () { if (continuous) { UpdateContinuous(); } else { UpdateDiscrete(); } }

推薦閱讀:

TAG:Unity遊戲引擎 | C | 遊戲開發 |