天天看點

《Unity 4 3D開發實戰詳解》一6.1 剛體

本節書摘來異步社群《unity 4 3d開發實戰詳解》一書中的第6章,第6.1節,作者: 吳亞峰 , 杜化美 , 張月霞 , 索依娜 責編: 張濤,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

unity 4 3d開發實戰詳解

在unity内建實體引擎中,首先要介紹的是剛體(rigidbody)的概念。包含有該類元件的遊戲對象,會遵循萬有引力定律,在重力的作用下,使物體垂直下落。剛體元件還會影響物體發生碰撞時的反應,使物體遵循慣性定律,并在其他物體運動沖擊作用下産生速度或者形變。

剛體作為實體引擎中的最基本元件,保證了所有物體受到重力的限制。unity開發平台中,對剛體設定了很多屬性和變量,并對應封裝了多個相關方法,下面進行分别介紹。

1.剛體屬性

為了利于開發者控制實體系統,unity提供了多個屬性接口。開發者可以通過更改這些參數來控制物體的實體狀态。實際開發中,這些參數都被詳細地羅列在屬性檢視器中,開發者很容易就可以對其進行更改。接下來對這些屬性進行介紹。

(1)品質(mass)

該屬性表示剛體的品質,其資料類型是float,預設值為1。其在屬性檢視器中的位置如圖6-1所示。該屬性的大小是有嚴格要求的,一般來說,大部分物體的品質屬性值接近0.1才符合日常生活的感官感受,一旦超過10.0,就會失去仿真所需達到的效果。

(2)平移阻力(drag)

該屬性是物體的平移阻力,其資料類型是float,初始值為0。drag屬性在屬性檢視器中的位置如圖6-2所示。在現實生活中,物體會受到各方面的影響,速度會漸漸衰減,為了模拟這一效果,unity設定了平移阻力屬性。這一屬性值越高,物體的速度衰減越嚴重。

(3)旋轉阻力(angular drag)

該屬性表示物體的旋轉阻力,其資料類型是float,初始值為0.05。其在屬性檢視器中的位置如圖6-3所示。當一個物體進行旋轉的時候,其旋轉的角速度也會受各方面影響衰減,為模拟這一現象,unity設定了旋轉阻力屬性。此屬性值越高,物體的角速度衰減越嚴重。

《Unity 4 3D開發實戰詳解》一6.1 剛體

(4)使用重力(use gravity)

該屬性表示的是該物體是否受到重力的影響,其資料類型是boolean,初始值為true。其在屬性檢視器中的位置如圖6-4所示。這一屬性被設為false時可以模拟物體在外太空狀态下的失重狀态。有時候也可以根據需要用于某些特殊的場合。

《Unity 4 3D開發實戰詳解》一6.1 剛體
注意 當該值被設定為false的時候,物體将不受重力影響,但剛體的其他特性還是存在的。

(5)是否遵循運動學(is kinematic)

該屬性表示本遊戲對象是否遵循牛頓運動學實體定律,其資料類型是boolean,初始值為false。其在屬性檢視器中的位置如圖6-5所示。如果該屬性被置為true,本物體的運動狀态将不受外力、碰撞和關節的影響,而隻受到動畫以及附加在物體上的腳本的影響。

另外,雖然當該屬性被置為true時物體将不受實體定律的限制,但是該物體還是會影響其他的物體,改變其他物體的運動狀态。在遊戲開發中此屬性會被經常用到,想象一下在第一人稱射擊遊戲中,敵人被擊殺後會倒地不動,因為這個敵人對象rigidbody的is kinematic屬性被設定為了true。

(6)插值(interpolate)

該屬性表示的是該物體運動的插值模式。其在屬性檢視器中的位置如圖6-6所示。在預設狀态下,插值interpolate是被禁用的,可以選擇interpolate模式,在此模式下實體引擎會在物體的運動幀之間進行插值,使得運動更加自然。

《Unity 4 3D開發實戰詳解》一6.1 剛體

不得不提的是,插值導緻了實體模拟和渲染的不同步,進而産生物體輕微抖動的現象。建議在開發中,對主要角色使用插值,而其他的則禁用此功能,以達到折中效果。

(7)當機旋轉(freeze rotation)

該屬性表示的是該物體的旋轉是否受到實體定律的限制。其在屬性檢視器中的位置如圖6-7所示。預設狀态下任意軸的旋轉是受實體定律控制的。該屬性的值是修改在每個軸上的旋轉屬性來實作的,實際開發中可以靈活地使用。

在第一人稱射擊遊戲中,通過此屬性去除實體屬性對旋轉的控制,可以使玩家完全控制視角旋轉。

(8)碰撞檢測模式(collision detection)

該屬性表示的是碰撞檢測模式。其在屬性檢視器中的位置如圖6-8所示。預設狀态下,碰撞檢測模式是discrete 。在沒有碰撞檢測的情況下,碰撞物體會穿過對方,産生所謂的“穿透”現象。為避免此類問題的發生,碰撞檢測工作是必須做的。

《Unity 4 3D開發實戰詳解》一6.1 剛體

關于碰撞模式的選擇,可選的有不連續模式(discrete)、連續模式(continuous)和動态連續模式(continuousdynamic),其中動态連續模式适用于高速運動的物體,但是耗費資源較大。連續模式僅僅可以用于球體、膠囊和盒子碰撞者的剛體,而且會嚴重影響物體的運動表現。是以大部分的物體采用不連續模式作為碰撞檢測模式。

2.剛體變量

為了擷取或者更改物體的運動狀态,unity還預留了多個變量接口,這些接口使得運動處理變得相當簡單。接下來将具體地介紹一下這些變量。

(1)剛體的速度(velocity)

此變量表示物體的速度值,在unity中機關1表示現實生活中的1米。在開發過程中,直接更改此變量的值并不是一種明智的做法,因為unity中物體的運動經過非常複雜的計算使得物體的運動自然平滑,如果有外加幹預,會迫使物體的運動模拟失真。

下面的代碼可以實作一個物體的速度驟增,以實作瞬移效果,具體代碼如下:

(2)是否使用重力(usegravity)

此變量表示目前的物體是否受到重力的限制。在開發過程中,靈活地更改此變量可以達到一些特殊的場景要求,比如在外太空環境下的失重狀态。

可以編寫代碼實作物體的失重狀态,具體代碼如下:

(3)當機旋轉(freezerotation)

此變量表示目前的物體的旋轉是否受到實體定律的限制。通過此變量,可以更改x、y、z三個方向中的某個方向的旋轉限制,以達到開發者想要達到的旋轉效果。

該變量使用的具體文法代碼如下所示:

(4)剛體的位置(position)

此變量表示了剛體的位置,改變此變量時,引擎會在實體階段結束後,将物體放置到指定的位置。

下面的腳本實作了将物體放置于原點的功能,具體代碼如下:

說明 這種做法不适用于旋轉物體,可以使用moveposition代替。

(5)剛體的旋轉(rotation)

此變量表示了物體的旋轉狀态,改變此變量時,引擎會在實體階段結束後,将物體旋轉到指定的狀态。

下面的腳本實作了設定物體無旋轉,具體代碼如下:

2   rigidbody.rotation = quaternion.identity;//将物體的旋轉狀态設定為原始态(無旋轉)

3 }

這種做法不适用于旋轉物體。可以使用moverotation方法來代替。

3.剛體常用方法

在講解了剛體的屬性與變量後,有必要講解一下unity提供的相關方法。

(1)給剛體施加力(addforce)

此方法被調用時,将會施加給剛體一個瞬時力,然後物體在力的作用下,産生一個初速度,接着物體在初速度的作用下開始運動。

下面的代碼實作了對物體施加豎直向上的力,具體代碼如下:

addforce方法盡量不要用在update方法中,因為這樣的方法在update中會被不停地調用,與被調用一次不同,這種是模拟了一種加速度的效果。

(2)移動剛體位置(moveposition)

此方法被調用時,會使剛體按照參數移動到某個位置。此方法經常用于fixedupdate方法中。具體用法如下列代碼所示:

(3)旋轉剛體(moverotation)

此方法被調用時,會使剛體按照參數旋轉到某個方位。此方法經常用于fixedupdate方法中。具體用法如下列代碼所示:

前面的内容簡單介紹了剛體的屬性、變量和常用方法。接下來這一部分将講解一下實體管理器(physics manager)的相關内容。

unity作為一個優秀的遊戲開發平台,其出色的管理模式是令人稱贊的。在unity中,不僅可以對單個分組進行屬性設定,也可以對場景全局進行設定。這一部分講解unity中場景的全局實體參數是如何設定的。

1.實體管理器預覽

(1)打開unity開發平台,在菜單欄中選擇“edit”選項,會彈出編輯清單,如圖6-9所示。在編輯清單中,選擇“project settings”選項,彈出全局設定清單,如圖6-10所示。在全局設定清單中選擇“physics”,即可進入實體管理器。

《Unity 4 3D開發實戰詳解》一6.1 剛體
《Unity 4 3D開發實戰詳解》一6.1 剛體

(2)按照第(1)步進行操作以後,會在屬性檢視器中呈現實體管理器編輯器,如圖6-11所示。

《Unity 4 3D開發實戰詳解》一6.1 剛體

2.實體管理器參數

在前面的内容中,講解了實體管理器的打開操作。接下來介紹的是實體管理器中的相關參數的含義和用法。

(1)重力(gravity)。

該屬性表示的是項目中的重力加速度,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-12所示,該屬性3個數值分别指定在x、y、z方向上的重力加速度,一般重力是豎直向下的,是以隻有y軸上有一個負值,大小預設為機關是-9.81米/(秒^2)。

(2)預設材質(default material)。

該屬性表示當物體沒有被指定實體材質的時候,該物體的預設材質。其在實體管理器中的位置,如圖6-13所示。預設狀态下是沒有指定值的,因為在unity中,每個物體的實體材質可能會有很大的不同,有時候指定預設材質并不是有太大的用途。

《Unity 4 3D開發實戰詳解》一6.1 剛體

(3)反彈門檻值(bounce threshold)。

該屬性表示的是項目中的反彈門檻值,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-14所示,如果兩個碰撞體的相對速度低于該值,那麼将不會反彈。該值也用于減少抖動,是以不建議設定為很低的值。

(4)休眠速度(sleep velocity)。

該屬性表示的是項目中剛體自動進入休眠時狀态的速度值。其在實體管理器中的位置如圖6-15所示。該值是休眠的預設線速度,低于該速度的物體将會進入休眠。如果沒有這種機制,項目中的所有物體将永遠都在計算中,對于資源的回收利用很不利。

《Unity 4 3D開發實戰詳解》一6.1 剛體

(5)休眠角速度(sleep angular velocity)。

該屬性表示的是項目中的休眠角速度,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-16所示,如果角速度低于該值,物體将進入休眠狀态。

(6)最大角速度(max angular velocity)。

該屬性表示的是項目中剛體最大的角速度值。其在實體管理器中的位置如圖6-17所示,設定最大值可以避免角速度數值不穩定現象的發生。在腳本中可以用文法rigidbody.maxangular velocity來更改此值。

《Unity 4 3D開發實戰詳解》一6.1 剛體

(7)最小穿透禁區(min penetration for penalty)。

該屬性表示的是項目中的最小穿透禁區,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-18所示,該屬性的具體含義是在碰撞檢測器将兩個物體分開前,可以穿透多少米的距離。較高的值會導緻較多的物體穿透,不過可以減少抖動。

(8)求解疊代次數(solver iteration count)。

該屬性表示的是項目中關節和連接配接計算過程中的疊代次數。其在實體管理器中的位置如圖6-19所示,決定了關節和連接配接的計算精度。求解疊代次數越高精度越高,但是次數過高會浪費過多的資源,不利于項目的正常運作,一般來說此值設定為7就可以适用于大多數情況。

(9)射線檢測命中觸發器(raycasts hit triggers)。

該屬性表示的是項目中的射線檢測命中觸發器,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-20所示。如果啟用,那麼進行射線檢測時命中碰撞體會傳回一個命中消息,如果關閉,則不傳回命中消息。

(10)層碰撞矩陣(layer collision matrix)。

該屬性表示的是項目中的層碰撞矩陣,該參數将被應用于所有剛體。其在實體管理器中的位置如圖6-21所示。定義層碰撞檢測系統的行為。

《Unity 4 3D開發實戰詳解》一6.1 剛體
《Unity 4 3D開發實戰詳解》一6.1 剛體
層碰撞矩陣在後面的介紹中會有比較詳細的解釋,此處不再贅述。

1.碰撞的使用

與碰撞相關的内容包括碰撞器(collision)類、碰撞檢測模式選擇和最小穿透禁區設定,後兩個内容已經在前面的内容中進行了詳細的介紹,這裡不再贅述。下面重點講解一下碰撞器類及其相關方法的使用。

(1)碰撞器類的變量如表6-1所示,碰撞器有很多變量供碰撞處理使用,其中除了碰撞接觸點(contacts)變量,其他變量都是隻讀的,讀者請務必注意。

《Unity 4 3D開發實戰詳解》一6.1 剛體

(2)碰撞器相關方法。

碰撞觸發(oncollisionenter)

此方法在碰撞發生時被系統自動調用。該方法會傳遞一個collision類,該類包含了碰撞點和相對速度等資訊。開發者可以利用這些資訊對物體進行碰撞處理,下面的代碼就是一個簡單的例子:

該方法隻有在兩個物體都遵循實體定律的情況下發生,即兩者的is kinematic屬性都為false。

碰撞狀态(oncollisionstay)

此方法在碰撞時兩物體接觸過程中被調用。該方法同樣會傳遞一個collision類,該類包含了碰撞點和相對速度等資訊,下面的代碼就是一個簡單的例子:

退出碰撞(oncollisionexit)

此方法在碰撞時停止觸碰剛體或者碰撞的時候調用。該方法同樣會傳遞一個collision類,該類包含了碰撞點和相對速度等資訊,下面的代碼就是一個簡單的例子:

**1 function oncollisionexit(collisioninfo : collision) { //碰撞結束

2   print("不再和" + collisioninfo.transform.name+"發生碰撞。"); //列印**碰撞結束資訊

2.睡眠的使用

(1)睡眠(sleep)。

該方法被調用時,會強制一個剛體進入睡眠狀态至少一幀的時間。一般用在awake方法中,設定腳本開始執行時剛體睡眠。剛體進入睡眠後,物體相當于沒有剛體存在,其具體的文法如下:

(2)強制喚醒(wakeup)。

該方法被調用時,會強制使一個處于睡眠狀态剛體被喚醒,其具體的文法如下:

繼續閱讀