王者榮耀是怎樣煉成的(三)unity組件與腳本

轉載請註明出處:http://www.cnblogs.com/yuxiuyan/p/7565345.html

上回書說到了unity的基本操作。這回我們來侃侃unity中的組件與腳本。

 

目錄結構

  一.組件與腳本簡介

  二.鼠標與鍵盤輸入

  三.使用變換組件移動遊戲物體

  四.物理組件之剛體

  五.物理組件之碰撞體

  六.剛體常用方法介紹

  七.剛體碰撞事件監測與處理

  八.剛體觸發事件監測與處理

  九.遊戲打包與發佈

  十.入門總結

 

 

一.組件與腳本簡介

1.組件

組件(Component),顧名思義,就是遊戲物體的組成部件。

這和我們對現實生活的認識是一致的。就比如說一臺主機,是有CPU,顯卡,主板,內存條等等組成的。這些部件就是主機的“組件”。這些組件一旦有不滿意的,隨時可以增刪改查。

Unity3D就是一個“組件式”的遊戲引擎,它使用各種各樣的的組件“拼裝”了遊戲物體,最終再把遊戲物體拼裝成遊戲。

上圖是一個Plane的自帶組件。

Unity3D爲我們提供了許多種類的組件。後期其實就是各種組件的使用和特性,以及它們能實現的功能和效果。

按照我們老祖宗的理論,五行是組成世界的最基本元素。那麼在Unity3D中,組件就是組成遊戲世界的最基本元素。

我總結出了上面一幅圖,這幅圖相當重要,大家需要認真看看。因爲這涉及到了遊戲物體與腳本中類和對象的聯繫。

 

2.Transform組件

在這裏提一個最最基本的組件之一——Transform組件。

Transform,中文爲“變換”,這個組件有三大基本屬性,Position(世界位置座標),Rotation(相對自身座標系的旋轉角度),Scale(相對於初始的縮放比例)。

這個組件是每一個遊戲物體都有的屬性,並且不能刪除。其實想想也是,在現實生活中,只要是一個物體必定有方位、旋轉、縮放的屬性。

通過修改這三大屬性的X\Y\Z值,我們就可以控制物體的“變換”信息了。這裏有一個小技巧,當把鼠標放到X\Y\Z上時,鼠標變成了可以左右拖動的標誌,可以直接左右拖動改變值,當然直接修改值也是ok的。

3.腳本

腳本(Script),也就是給遊戲物體寫的代碼,用來控制遊戲的邏輯。在Unity3D 5.x版本後,只支持C#腳本和JavaScript腳本。在國內開發的主流的C#。

4.創建與管理腳本

我們說過,Assets文件夾是總管,所以我們在Assets中新建一個Scripts文件夾,用來管理腳本資源。

在Scripts文件夾中右鍵-->Create-->C# Script。C#腳本文件的後綴是“.cs”。雙擊腳本文件,可以調用代碼編輯器進行編輯。

5.原始腳本代碼組成

在上一步我們新建了一個腳本,這次打開它看看究竟是什麼東東。

ok,我們看到這次unity幫我們新建立了一個類,類名就是我們的腳本文件名。然後它繼承自MonoBehaviour類,這個類呢,在unity的地位和作用,類似於在java中的Object類,所以重要性不言而喻。有興趣的童鞋可以去看看這個類的實現。可以看一下這篇文章:http://blog.csdn.net/yuyueliuliu/article/details/43795333。還能看到,這個腳本using了UnityEngine的引擎。然後unity還幫我們寫了兩個方法Start()和Update()。

Start():當遊戲運行起來,這個方法就會馬上執行且只執行一次。由此看來,這個方法非常適合做初始化的工作。事實上也是這樣的,我們常常在這個方法中做一些GetComponent()的操作。

Update():循環調用,每一幀就調用一次。我大致測了一下,一般的場景大概是每秒60次的樣子。

這裏還要介紹一個方法:Debug.Log()。這個用來輸出調試。如果你的目標是“helloworld”,ok,這個方法正好就是這樣。

順便提一句,Start()和Update()都是unity內部的“事件方法”,不需要我們人工調用,系統會自動調用和管理這些方法的。

6.使用腳本

  • 直接將腳本拖拽到Hiearchy面板的物體上
  • 直接將腳本拖拽到物體的Inspector面板上

 運行遊戲,腳本自動執行。

這是一個first.cs腳本:

using UnityEngine;
using System.Collections;

public class first : MonoBehaviour {

    void Start () {
        Debug.Log("這是Start方法");
    }
    
    void Update () {
        Debug.Log("這是Update方法");
    }

}

 

把它添加到燈光上,運行遊戲,控制檯效果:

 

 

 

二.鼠標與鍵盤輸入

上面我們已經知道了C#腳本的大致套路。說到寫代碼就是各位童鞋的長處了。這次我們實現一下讓遊戲讀出我們的輸入。

unity很友好地爲我們都寫好了方法,我們只需要調用這些接口就ok了。

1.獲取鍵盤輸入

 

案例如下:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class InputTest : MonoBehaviour {
 5 
 6     void Update () {
 7         if (Input.GetKey(KeyCode.A))
 8         {
 9             Debug.Log("按下了A鍵");
10         }
11         if (Input.GetKeyDown(KeyCode.A))
12         {
13             Debug.Log("GetKeyDown");
14         }
15         if (Input.GetKeyUp(KeyCode.A))
16         {
17             Debug.Log("GetKeyUp");
18         }
19     }
20 }

 2.獲取鼠標輸入

直接上方法。

 

用法和監聽鍵盤輸入類似,在這裏就不再寫代碼舉例了(笑~)。

 

三.使用變換組件移動遊戲物體

上面提到了鼠標鍵盤監聽控制,也提到了Transform組件,我們利用腳本,可以把兩者組合起來,實現通過鍵盤讓遊戲物體動起來!

 

備註:腳本也可以看成組件,一般是要控制哪個遊戲物體就把腳本掛載到哪個物體上。

下面就是一個例子:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class StudentMove : MonoBehaviour
 5 {
 6     private Transform trans;
 7 
 8     // Use this for initialization
 9     void Start()
10     {
11         trans = gameObject.GetComponent<Transform>();
12     }
13 
14     // Update is called once per frame
15     void Update()
16     {
17         if (Input.GetKey(KeyCode.W))
18         {
19             trans.Translate(Vector3.forward * 0.1f, Space.World);
20         }
21         if (Input.GetKey(KeyCode.A))
22         {
23             trans.Translate(Vector3.left * 0.1f, Space.World);
24         }
25         if (Input.GetKey(KeyCode.S))
26         {
27             trans.Translate(Vector3.back * 0.1f, Space.World);
28         }
29         if (Input.GetKey(KeyCode.D))
30         {
31             trans.Translate(Vector3.right * 0.1f, Space.World);
32         }
33     }
34 }

 

把這個腳本,拖到遊戲物體的Inspector面板上,然後點擊遊戲的“運行”按鈕,可以發現我們已經可以通過鍵盤的W\A\S\D鍵控制物體的前左後右的移動了!amazing!

 

 

 

 

四.物理組件之剛體

在上面我們通過Transform組件實現了物體位置的移動,但是仔細研究一下發現了以下幾個特點:

  • 移動的物體會“穿透”場景中其他的物體模型
  • 移動的物體不會受到重力影響(即使到達場景之外,也不會下落)

 這樣看起來物體動是動了,但是不太真實,和我們現實生活中有很大差別。

大家應該都聽過或者玩過《憤怒的小鳥》,小鳥的拋物線運動,石頭的坍塌,都是符合物理規律的。

我們說過,組件是構成遊戲物體的基礎。所以,我們需要其他組件來使物體符合物理規律。

1.剛體

 剛體(Rigidbody),屬於物理類組件。添加了剛體組件的遊戲物體,就有了重力,就會做自由落體運動,也就實現了現實物體的物理運動。

選擇遊戲物體-->菜單欄點擊Componment-->Physics-->Rigidbody,給物體添加剛體組件成功!

2.常用屬性

看着上圖,我們瞭解一下它的幾個常用屬性。

Mass[質量],可以設置物體的質量,你可以認爲單位是KG。

Drag[阻力],一般是指空氣阻力,0表示沒有空氣阻力,空氣阻力越大,物體自由落體越慢。當值很大時,物體甚至會停止運動,漂浮在空中。

Angular Drag[角阻力],收到扭曲力時候的空氣阻力,0表示沒有阻力,當值很大時,物體甚至會停止運動。

Use Gravity[使用重力]。當勾選之後,如果物體掉入場景之外,會落入“深淵”。

 

3.在腳本中使用剛體組件移動遊戲物體

直接上腳本

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class RigidbodyMove : MonoBehaviour
 5 {
 6     private Transform trans;
 7     private Rigidbody rigid;
 8 
 9     // Use this for initialization
10     void Start()
11     {
12         trans = gameObject.GetComponent<Transform>();
13         rigid = gameObject.GetComponent<Rigidbody>();
14     }
15 
16     // Update is called once per frame
17     void Update()
18     {
19         if (Input.GetKey(KeyCode.W))
20         {
21             rigid.MovePosition(trans.position + Vector3.forward * 0.1f);
22         }
23         if (Input.GetKey(KeyCode.A))
24         {
25             rigid.MovePosition(trans.position + Vector3.left * 0.1f);
26         }
27         if (Input.GetKey(KeyCode.S))
28         {
29             rigid.MovePosition(trans.position + Vector3.back * 0.1f);
30         }
31         if (Input.GetKey(KeyCode.D))
32         {
33             rigid.MovePosition(trans.position + Vector3.right * 0.1f);
34         }
35     }
36 }

 代碼很簡略,但是卻實現了像現實物體一樣的物理運動,很神奇。

 

 

五.物理組件之碰撞體

 1.碰撞體

上面使用剛體組件的物體,在場景中其他物體可以產生碰撞的效果。其實碰撞目標物體的,是專門有一個組件來負責的,就是碰撞體組件(Collider)。

換個說法,我們控制的物體A與物體B的碰撞,實質上是物體A與物體B的碰撞體組件發生了作用關係。 

碰撞體可以理解成我們模型的“外骨骼”。

這是一個什麼也沒有動的原來的Cube。

 把物體的渲染器(上面的Renderer的勾選去掉)屏蔽,可以發現物體的碰撞體長得什麼樣子:

顯示的就是Cube外層的碰撞體組件。

只要我們創建了物體,unity就默認爲我們加上了碰撞體組件,沒有碰撞體的剛體是沒有意義的,就失去了剛體本該有的物理特性。

換句話說,物理特性是剛體組件和碰撞體組件一起表現出來的。

其實這一對“好基友”有很多很多的故事,大致總結了一下。

 

碰撞體組件按照它們的形狀,大致可以分爲以下幾類。

2.Box Collider

盒子碰撞體,形狀是立方體,用來包裹盒子狀的模型,比如箱子、門、房子,等等。有幾個常用屬性:

Is Trigger:設置是否爲觸發器。這個屬性非常重要,在後面講觸發器會經常使用。

Material:物理材質。

Center:碰撞體也可以設置中心點。一般來說碰撞體中心點就是物體的幾何中心點。

Size:設置物體的“外骨骼”的尺寸。

 3.Sphere Collider

球形碰撞體,和上面的盒子碰撞體基本類似,Radius是半徑。

4.Capsule Collider

膠囊碰撞體,屬性和球形碰撞體類似,Direction是指設置它的高度的方向。

5.Mesh Collider

網格碰撞體,用來包裹複雜結構的模型

Mesh:根據指定的網格,生成碰撞體。

 

 

六.剛體常用方法介紹

有了組件,必然有新帶來的方法。

1.AddForce()

作用:給剛體一個力,使剛體按照“世界座標系”進行運動。

其中的ForceMode是力的模式,是一個枚舉類型,決定以什麼樣的方式添加力給剛體。

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class ForceTest : MonoBehaviour
 5 {
 6     private Rigidbody rigid;
 7     void Start()
 8     {   //獲取物體的剛體組件
 9         rigid = gameObject.GetComponent<Rigidbody>();
10     }
11     void Update()
12     {   //給剛體施加一個相對世界座標系向前的力
13         rigid.AddForce(Vector3.forward, ForceMode.Force);
14     }
15 }

 

2.AddRelativeForce()

作用:給剛體添加一個力,讓剛體按照“自身座標系”進行運動。

由此可以知道,AddForce()和AddRelativeForce()是非常像的,這倆其實就是雙胞胎,只不過一個是相對世界座標系,另一個是相對自身座標系罷了。

3.FixedUpdate()

這個是固定的更新方法。這個方法值得說道說道。一查網上資料還真不少,那就不獻醜了~

Update()方法是每一幀刷新一次,但是時間間隔是不確定的。而FixedUpdate()方法是固定時間間隔(默認0.02秒)刷新一次。

這個值是可以自己設定的。Edit-->Project Settings-->Time-->Fixed Timestep。

基本上和物理相關的操作,代碼都是寫在FixedUpdate()方法裏面。如果你寫在了Update()裏,會出現卡頓的現象。

 

 

七.剛體碰撞事件監測與處理

1.碰撞事件簡介

啥叫“碰撞事件”呢?當一個用剛體控制的物體與另外一個物體碰撞時,就會觸發碰撞事件。

注:目標物體必須帶有Collider組件。

碰撞 Collision

比如,一個射擊類遊戲,我們發射了子彈,子彈是一個由剛體控制運動的物體。子彈射中了敵人,我們怎麼監測這個碰撞呢?

2.碰撞事件監測方法

  • OnCollisionEnter(Collision)   //當碰撞開始時調用,只會調用該方法一次
  • OnCollisionExit(Collision)     //當碰撞結束時調用,只會調用該方法一次
  • OnCollisionStay(Collision)     //當碰撞進行中時,會持續調用該方法

這個Collision參數是什麼呢?

這個是“碰撞”的一個類,用來傳遞碰撞信息。

Collision.gameObject屬性,與當前物體碰撞的物體的引用。

gameObject.name屬性,當前物體的名字。

上代碼示例:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class CollisionCube : MonoBehaviour {
 5 
 6     void OnCollisionEnter(Collision coll)
 7     {
 8         if(coll.gameObject.name != "Ground")
 9             Debug.Log ("Enter " + coll.gameObject.name);
10     }
11 
12     void OnCollisionExit(Collision coll)
13     {
14         if(coll.gameObject.name != "Ground")
15             Debug.Log ("Exit " + coll.gameObject.name);        
16     }
17 
18     void OnCollisionStay(Collision coll)
19     {
20         if(coll.gameObject.name != "Ground")
21             Debug.Log ("Stay " + coll.gameObject.name);                
22     }
23         
24 }

 

八.剛體觸發事件監測與處理

1.觸發事件簡介

將碰撞體組件上的Is Trigger選項選中,當前的遊戲物體的碰撞體組件就變成了觸發器。

我想大家應該都理解“觸發器”的概念。

注:移動的剛體物體都會穿透碰撞體勾選了“Is Trigger”選項的物體。

當一個用剛體控制的物體進入到另一個物體的觸發器範圍內,就產生了觸發事件。

這個不與目標物體發生直接的碰撞(接觸),而是隻要進入目標物體的“觸發範圍”就能執行某些操作。

那怎麼設定“觸發範圍”呢?其實和我們上面設置碰撞體範圍的方法是一致的。

2.觸發事件監測方法

  • OnTriggerEnter(Collider)  //當進入觸發範圍開始時調用,只會調用該方法一次
  • OnTriggerExit(Collider)   //當退出觸發範圍開始時調用,只會調用該方法一次
  • OnTriggerStay(Collider)     //在觸發範圍內,會持續調用該方法

這個Collider參數是什麼呢?

這個是“碰撞體”的一個類,用來傳遞觸發信息。

Collision.gameObject屬性,進入觸發範圍內的目標物體的引用。

gameObject.name屬性,當前物體的名字。

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class TriggerCube : MonoBehaviour {
 5 
 6     void OnTriggerEnter(Collider coll)
 7     {
 8         Debug.Log (coll.gameObject.name+"on trigger enter");
 9     }
10     void OnTriggerStay(Collider coll)
11     {
12         Debug.Log (coll.gameObject.name+"on trigger stay");
13     }
14     void OnTriggerExit(Collider coll)
15     {
16         Debug.Log (coll.gameObject.name+"on trigger exit");
17     }
18 }

 

 

 

九.遊戲打包與發佈

好了,當我們製作好了一個遊戲,怎麼把它發佈到各個平臺呢?

其實很簡單。untiy已經幫我們做好了絕大部分事情。

我們要做的事情:

1.Build Settings[生成設置]

 

 

2.Player Settings[詳細設置]

3.成品介紹

一個exe文件,一個data數據文件夾,兩者缺一不可。

 

 

十.入門總結

這個階段我們從最簡單的組件與腳本學起,介紹了鼠標鍵盤的交互,怎麼移動物體,瞭解了剛體、碰撞體以及常用的幾個方法,還學習了怎麼打包發佈。那麼unity的基本操作差不多告一段落。雖然還有很多沒有介紹到,那我們在做demo的過程中再學再用吧。我還把上面介紹到的所有的方法和屬性寫了一個思維導圖文件,縮略圖:

 

詳細的地址:鏈接:http://pan.baidu.com/s/1dFMXvpf 密碼:8xq0

ok,今天告一段落。

 ------------------------------------9.26更新---------------------------------------------------------------------------------------------------------------

最近規劃了一下,發現看似簡單的一個demo做起來需要用到許多unity的其他知識,什麼動畫系統,粒子系統,物理引擎,所以準備開一個新的案例,如《貪吃蛇大作戰》等,補充自己的知識後,再來更好地做這個農藥的demo。再加上本人還是某不知名雙一流大學的學生,課程比較緊,期間會穿插其他知識,所以這個專欄更新會比較慢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章