關鍵詞:Unity / 入門 / 遊戲對象 / 場景 / 快捷鍵 / Terrain / 資源包
1. 遊戲對象和基本操作 #
1.1 場景和遊戲對象 #
遊戲項目
|
/ \
場景A 場景B ... ...
|
/ \
遊戲對象1 遊戲對象2 ... ...
|
/ \
組件 組件 ... ...
場景顯示在 Scene 裏面,Hierarchy 裏面是遊戲對象比如 3D Object: Main Camera、Plane等;
按住 Q/W/E/R/T 同時點擊鼠標操作:Q平移場景/W平移選中的遊戲對象/E旋轉/R縮放工具/T操作2D的精靈工具,分別對應 Unity 編輯器左上角的功能圖標的快捷鍵;
鼠標右鍵:移動視圖;
[遊戲對象]
- 一個遊戲項目由多個場景組成,在場景中,一個角色,一個模型,一個特效,都是遊戲對象。
- 場景就是由多個遊戲對象組成的;
- 每個遊戲對象身上都會有多個組件,使遊戲對象具備相應的特性、實現相應的功能;
1.2 快捷鍵操作 #
- 選中任何遊戲對象,按F鍵或者雙擊,都可以定位到該遊戲對象;
- 按下鼠標右鍵 + WASD 鍵進行場景漫遊;
- 按下 Alt + 鼠標左鍵旋轉視角;
- 按下鼠標右鍵旋轉視角;
- QWERT工具分別是手型工具、平移工具、旋轉工具、縮放工具和 2D 工具;
1.3 Terrain 地形系統 #
- 提升/下沉地形工具
- 平坦地形工具
- 平滑地形工具
- 植樹工具
- 地表細節工具
從網上找一些地形貼圖資源,自己使用地形編輯器編輯一個新的地圖;
1.4 資源包的導入 #
.unitypackage 後綴文件
1.5 攝像機 #
在Unity中攝像機決定遊戲最終的顯示效果
同一個場景中允許存在多個攝像機
1.6 世界座標系和本地座標系 #
世界座標 Global 是整個 3D 場景的座標系;
本地座標 Local 是某個遊戲對象內獨立的座標系;
(遊戲對象可以有子對象,世界座標與本地座標是相對的)
1.7 網格
要想讓模型出來,網格是必須的(好比人的骨架);
1.8 紋理
使模型表面賦有更多的細節,就需要給它添加紋理;
比如:在Assets中新建一個material材質球 拖拽到 Object 上,通過右側的面板修改材質球上的紋理屬性間接修改Object
1.9 材質和着色器
材質能夠將紋理應用在模型上,着色器決定紋理呈現出的最終效果;
2. 工程與應用程序 #
項目目錄下:
- Assets 裏面存放的是項目所需要的資源;
- Library 裏面存放的是所需要的庫文件;
- ProjectSettings 裏面存放的是工程設置文件;
- Temp 裏面存放的是臨時文件;
項目框架:
一個工程裏面有多個場景,一個場景中有多個遊戲對象,每個遊戲對象又有多個組件;
工程(Project)
|
/ \
場景(Scene) 場景(Scene) ... ...
|
/ \
遊戲對象(GameObject) 遊戲對象(GameObject) ... ...
|
/ \
組件(Component) 組件(Component) ... ...
每個場景可以理解爲每個界面;
組件開發:
遊戲物體想要實現什麼功能,只需要添加對應的組件即可,我們可以在Inspector視圖中查看當前遊戲對象身上的組件,修改組件的屬性; (Inspector)
- Transform 組件,決定物體的位置,旋轉和縮放;
- Mesh Filter 組件,顯示網格;
- Box Collider 組件,用來給物體添加碰撞器;
- Mesh Renderer 組件,可以給物體添加材質,紋理以及渲染的方式;
腳本組件:
腳本也是一種特殊的組件;
創建腳本;
在腳本中設置公共字段作爲組件屬性;
在腳本中通過方法獲取遊戲對象和組件;
用Mono編輯腳本
using UnityEngine;
using System.Collections;
// 如果我們的腳本需要掛載到遊戲對象身上,就需要繼承於 MonoBehaviour
public class TestCS : MonoBehaviour {
public int age;
public string name;
// Use this for initialization
void Start () {
// gameObject 表示當前腳本組件所掛載的遊戲對象
// unity 中輸出到控制檯使用 print 或者 Debug.log
print ("Test 腳本掛在到了 " + gameObject.name + " 的身上");
// 每個遊戲對象上都至少有一個組件,叫做 Transform
// transform 表示當前遊戲對象身上的 Transform 組件
print(transform.position.x);
print(name + age);
}
// Update is called once per frame
void Update () {
}
}
運行結果:
對應的Inspector:
可以再添加一個腳本Demo.cs,修改TestCS.cs的屬性,可以改變Cube的Script內容
using UnityEngine;
using System.Collections;
public class Demo : MonoBehaviour {
// Use this for initialization
void Start () {
// GameObject de fangfa GetComponent, nenggou
// huoqu dangqian youxi duixiang shenshang zhiding de leixing de zujian duixiang
TestCS t = GetComponent<TestCS> ();
t.age = 24;
t.name = "Da Wang";
t.Log();
}
// Update is called once per frame
void Update () {
}
}
結果截圖:
3. Unity 腳本 #
3.1 生命週期 #
Awake –> OnEnable –> Start
==》Update –> LateUpdate ==》
OnDisable –> OnDestroy
using UnityEngine;
using System.Collections;
// 繼承於 MonoBehaviour 的類叫做運行時類,運行時類都不能手動實例化,eg:不能 new: Test t = new Test()
public class Test : MonoBehaviour
{
// 這些方法都不是 MonoBehaviour 中定義的方法,而是通過反射調用的一些事件。方法名寫錯不會報錯
// 這些方法定義了一個腳本從被加載到被銷燬的過程中,腳本的生命週期
// 1.每當腳本被加載時調用,調用 1 次;在Awake中做一些初始化操作(放 public 字段);
void Awake ()
{
// 初始化 public 成員
print ("Awake");
}
// 2. 在每次激活腳本的時候就會調用 OnEnable,比如計時器重置;
void OnEnable ()
{
print ("onEnable");
}
// 2. 在第一次調用 Update 之前調用一次 Start 方法,然後中途不管激活取消激活,都不會再調用了
// 在Start方法中也可以做一些初始化操作(主要放私有字段);
void Start ()
{
print ("Start");
}
// 3.每幀都會調用一次 Update,每秒接近60幀,所以每秒大概調用60次左右
void Update ()
{
print ("Update");
}
// 4. 在Update調用之後進行調用,刷新其它邏輯的時候
void LateUpdate ()
{
print ("LateUpdate");
}
// 5. 取消激活狀態後調用
void OnDisable ()
{
print ("OnDisable");
}
// 6.被銷燬時調用一次
void OnDestroy ()
{
print ("OnDestroy");
}
// 用來寫 UI 的,持續調用 - 調用頻率高 IMGUI代碼需要寫在 OnGUI 方法中
void OnGUI ()
{
print ("OnGUI");
}
// 以固定的頻率調用(跟圖像刷新無關,不受圖像刷新幀速率的影響)
// 一般把處理物理的代碼放在這裏
void FixedUpdate ()
{
print ("FixedUpdate");
}
}
//public class A{
// public void T(){
// Test t = new Test ();// wrong
// }
//}
3.2 Input 類 #
Input 獲取鍵盤事件:
- Input.GetKey()
- Input.GetKeyDown()
- Input.GetKeyUp()
using UnityEngine;
using System.Collections;
// 繼承於 MonoBehaviour 的類叫做運行時類,運行時類都不能手動實例化,eg:不能 new: Test t = new Test()
public class Test : MonoBehaviour
{
void Start ()
{
// print ("Start");
}
// 獲取用戶事件需要使用 Input 類
// GetKeyDown 按鍵按下 & GetKeyUp 按鍵彈起 & GetKey 檢測持續按鍵的事件
void Update ()
{
// 每幀都需要監聽用戶事件
// 在當前這一幀中如果用戶按下了 W 就會返回 true, 否則返回 false
if (Input.GetKeyDown (KeyCode.W)) {
print ("往前走.");
}else if(Input.GetKeyDown(KeyCode.S)){
// Debug.Log ("往後退.");
print ("往後退.");// print 只能在 MonoBehaviour 的子類中使用
}
if(Input.GetKeyUp(KeyCode.Alpha1)){
print ("彈起了 1 鍵");
}
if(Input.GetKey(KeyCode.F)){
print ("按了 F 鍵");
}
// GetMouseButtonDown用來檢測鼠標按鍵按下的事件 &
// 參數 0 表示鼠標左鍵 & 參數 1 表示鼠標右鍵 & 參數 2 表示中鍵
if(Input.GetMouseButtonDown(0)){
print ("按下了鼠標左鍵");
}
if(Input.GetMouseButtonUp(0)){
print ("彈起了鼠標左鍵");
}
if(Input.GetMouseButton(0)){
print("持續按下了鼠標左鍵");
}
}
}
結果截圖:
Name Tag ActiveSelf SetActive() GetComponent() AddComponent()
GetComponent() AddComponent()
Destroy() FindGameObjectWithTag() FindGameObjectsWithTag()
3.3. GameObject #
using UnityEngine;
using System.Collections;
// 繼承於 MonoBehaviour 的類叫做運行時類,運行時類都不能手動實例化,eg:不能 new: Test t = new Test()
public class Test : MonoBehaviour
{
// GameObject - 遊戲對象類
void Start ()
{
// 通過 gameObject 獲取當前腳本所掛載的遊戲對象
// 一般來說, 在屬性視圖中能夠看到或修改的屬性, 也能夠在腳本中進行獲取並且修改
// 1. 獲取 & 設置遊戲對象的名字
print ("gameObject.name => " + gameObject.name);
gameObject.name = "小胡 Cube";
print ("經修改的 gameObject.name => " + gameObject.name);
//2. 獲取 & 設置遊戲對象的 Tag
print ("gameObject.tag => " + gameObject.tag);
gameObject.tag = "Player";
print ("經修改的 gameObject.tag => " + gameObject.tag);
// 3. 獲取 & 設置當前遊戲對象的激活狀態
print ("gameObject.activeSelf 是否激活 => " + gameObject.activeSelf);
gameObject.SetActive (false);
print ("經重置的 gameObject.activeSelf 是否激活 => " + gameObject.activeSelf);
// 4. 獲取遊戲對象身上的組件 eg: transform
// 在 Test.cs 中獲取 CubeController 組件
CubeController c = gameObject.GetComponent<CubeController> ();
print (c.balabala); // 獲取組件
Light l = gameObject.AddComponent<Light> (); // 添加組件
// 5. 通過 tag 的值查找遊戲對象
GameObject g = GameObject.FindGameObjectWithTag ("Player");
g.name = "小胡 Sphere";
// 另一種寫法
GameObject gg = GameObject.FindWithTag ("Player");
// 6. 通過遊戲對象名查找遊戲對象
GameObject ggg = GameObject.Find ("Main Camera");
ggg.name = "主攝像機";
// 7. 通過 tag 值查找多個遊戲對象
GameObject[] gs = GameObject.FindGameObjectsWithTag("Player");
}
void update ()
{
// if (Input.GetKeyDown (KeyCode.S)) {
// // 2 秒鐘之後銷燬遊戲對象
// GameObject.Destroy (gameObject, 2f);
// }
}
}
using UnityEngine;
using System.Collections;
public class CubeController : MonoBehaviour {
public string balabala;
}
運行結果
4. Unity 常識知識點總結 #
4.1 關於程序 #
基本組成:
- Sence 場景,類似於 Flash 中的 stage, 用於放置各種對象
- GameObject, 可以攜帶各種 Component;
每個 GameObject 至少帶有 Transform 組件, 所有的組件都可以從頂部菜單 Component 裏面找到並添加給遊戲對象;
腳本語言:
- C# / Javascript / boo (前兩者使用較爲廣泛, 網上教程以前兩者爲主, 個人推薦 C#),一般的繼承 MonoBehavior 類的腳本都需要依附的場景中的對象上才能被執行.
GUI(用戶圖形界面):
- 用於製作按鈕/文本顯示/滾動條/下拉框等常用圖形操作界面元素,使用 GUISkin 和 GUIStyle 可以自定義樣式;
- 系統自帶 GUI;
- 各類 GUI 插件, NGUI/EZGUI 等;
預製:
- 用於程序運行時,動態實例化對象的”母體”,比如,在射擊類遊戲中,子彈的生成就可以使用實例化預製的方式來實現,可以定義它的各種屬性方法, 然後在使用的時候直接實例化一個實例;
- 在 project 面板右擊選擇 Create -> Prefab 新建一個預製, 將 Hierarchy 面板中要製成的對象拖到這個新建預製上即可;
標籤:
tag 用於辨別物體, 與 name 類似,使用對象的 tag 和 name 都可以找到對應的物體, GameObject.Find(“name”) 或 GameObject.FindWithTag(“Tag”); 默認的是 Untagged,可以通過 Inspector 面板裏面 Tag 的下拉菜單選擇 Add Tag 項來添加新的標籤; Inspector -> TagManager -> Tags 裏的 size 來增加標籤的數量, 每個 Element 內都填入新標籤的名字;
層:
在使用某些功能的時候, 可以通過層來過濾不需要運用該功能的對象, 也就是把該功能運用到特定的層, 比如, 相機的 Culling Mask 屬性, 通過選擇特定層可以實現只顯示位於被選中的層的對象.
層的添加也是在標籤管理器中, Unity 已經設置了8個層,你是不能對這8個層進行修改的,你可以從第9個(也就是 user layer8)開始添加你定義的層;
資源:
- .unitypackage 格式的文件可以直接 import 到 unity 中,記住最好是在打開 unity 的情況下,在 project 面板裏右擊,然後在 import packages 中選中你要導入的資源;
- 可以 export package 導出場景成爲 .unitypackage 資源包
在工程面板可以 import new assests 可以導入其他形式的資源, 如, 模型/音頻/視頻等, 也可直接從外部文件夾中拖入
物理引擎:
unity 使用 nvidia PhysX 物理引擎
碰撞器: 各種基本體的碰撞器(box/sphere/capsule/cylinder), 網格碰撞器(mesh collider),車輪碰撞器(Wheel collider),地形碰撞器(terrain collider) 碰撞器組件在你選中對象的時候會以綠色框顯示;
- 碰撞檢測: 碰撞器碰撞檢測 / 光線投射(射線) / 觸發器碰撞檢測, 通過碰撞檢測可以得到與當前對象發生碰撞的對象信息, 使用碰撞的相關函數 OnCollisionEnter(碰撞器碰撞檢測) / OnTriggerEnter(觸發器碰撞檢測) / Physics.Raycast(光線投射)獲取;
- 剛體: 模擬物體物理現象的基礎, 加了剛體組件才能模擬重力 / 阻力等;
力: 作用於剛體,你只要通過添加各種力, 就可以使剛體表現出跟現實中一樣的受力情況;
粒子系統:
兩種形式, 一種以物體攜帶例子系統組件的形式實現, 另一種是直接使用粒子系統 GameObject(3.5 以後)
- 粒子系統 GameObject: GameObject – Create Other – Particle System
粒子系統組件: 粒子發射器(Particle Emitter, 有 Ellipsoid Particle Emitter 和 Mesh Particle Emitter 兩種類型的粒子發射器, 主要有 粒子產生 / 數量 / 速度 / 大小 / 存活時間等參數設置), 粒子動畫器(Particle Animator, 主要負責粒子產生後直至粒子消亡的行爲變化的控制, 包括運動過程中的旋轉 / 受力等), 粒子渲染器(Particle Renderer, 主要是負責給予粒子的渲染,陰影,材質等設定)
Camera(相機):
相機視角: 透視(可調整透視角度) / 正交(沒有透視效果)
- Skybox: 只在 Game 窗口可見, 需要 skybox 類型的 shader, 以及附在其上的六面貼圖紋理
- 第一人稱視角: 角色不出現在視野中, 相機看到的就像角色雙眼看到的一樣
- 第三人稱視角: 能在視野中看到角色, 相機一直跟着角色運動.
可以使用導入 Unity 自帶的 Character Controllers 資源包, 裏面有第一人稱和第三人稱的原型
光照系統:
- 常見燈光類型: 平行光(Directional light, 無衰減, 模擬太陽光)
- 聚光燈(spotlight, 從一點向某一方向反射錐形光束, 有衰減, 聚光效果)
- 點光源(Point light, 從一點向外輻射, 有衰減)
- 烘焙: 將靜態光影效果渲染到紋理上, 減少燈光和陰影帶來的開銷
- 陰影: 分爲 hard shadows 和 soft shadows 兩種, 前一種陰影比較重, 後一種相對柔和.
- 要產生陰影,還需要將投射陰影的對象的 Cast shadows 都選, 將接受陰影的對象的 Receive shadows 勾選, eg: 你要讓樹在地面上產生陰影, 那就得讓樹投射陰影, 然後讓地面接受陰影才行;
地形系統:
選擇頂部菜單 Terrain – creat terrain 創建一個地形
地形有一組地形工具用來繪製地形的高度, 生成各種地貌, 並且可以對地表運用紋理, 還可以添加樹,草等地表植被.
4.2 關於美術 #
3d 模型 / 材質 / 紋理(貼圖)
shader(着色器, Unity 本身擁有幾十種 shader, 也可以根據自己的需要使用 shaderLab 語言來編寫 shader,一般可以只用 Unity 自帶的和網上流傳的)
4.3 關於發佈 #
關於 Player settings 播放器設置的話這裏暫且不多說,發佈的時候通過 player setting 進行發佈設置,每個平臺都有對應的設置參數,根據需要來設置,主要 是關於程序圖 標、分辨 率、渲染 等設置, 大家可以 自己試試 (有些參 數只有 pro 版才能設置)。
下面我們來看看 build settings 對話框,左側是可發佈的平臺(Unity 跨平臺性 很強大,4.0 已支持發佈至 10 種平臺:IOS、Andriod、Windows、Mac、Linux、 Webplayer、Flash、PS3、Xbox360、Wii u),右側是對應平臺的發佈設置,一 般初學的話,只要會發佈單機版的和 webplayer 的就差不多了,這兩個的話, 右側的發佈選項按照默認的設置就可以,當然單機版要在 Target Platform 中選 擇對應的操作系統,webplayer 的話這裏我給大家介紹前兩個參數,Streamed 顧名思義就是在網絡上下載的時候以流的形式,Offline Deployment,這個是 可以在離線(斷網)狀態下本地運行你的 webplayer 程序(這裏需要注意的是, 默認情況下你每次打開 webplayer 程序的時候,瀏覽器都會自動去訪問官網更 新 webplayer 插件,如果你沒勾選這個選項而又在沒有聯網的狀態下運行 webplayer 的話是無法運行的)
End.
Note by HF.