# Unity 引擎入門實踐

關鍵詞: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 關於程序 #

基本組成:

  1. Sence 場景,類似於 Flash 中的 stage, 用於放置各種對象
  2. 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.


發佈了104 篇原創文章 · 獲贊 63 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章