基礎1——遊戲物體和腳本——造一個鍾
首先是匯總地址
雪之下雪乃:純文字和圖片的Unity教程-系列概述和匯總本節將會涉及到:
- 用最基礎的遊戲物體造一個鍾
- 寫C#腳本
- 讓鍾旋轉起來以顯示時間
- 控制鐘的指針
這是本教程的第一篇,將會使用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(); } }
推薦閱讀: