本節書摘來異步社群《unity 4 3d開發實戰詳解》一書中的第6章,第6.2節,作者: 吳亞峰 , 杜化美 , 張月霞 , 索依娜 責編: 張濤,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
unity 4 3d開發實戰詳解
在上一節中,講解了剛體的主要特性,在本節中将對碰撞器(collider)進行具體介紹。碰撞器是unity内建實體引擎中另外一個很重要的概念。弄清楚碰撞器的概念對于unity開發新手來說是很重要的。
unity中内建的碰撞器主要包括6種,具體情況如下所述。
盒子碰撞器——boxcollider
盒子碰撞器是一個基本的方形碰撞器原型,可以被調整成不同大小的長方體,能夠很好地用于門、牆、平台等,也能夠用于角色的軀幹或者車輛等交通工具的外殼。
一般地,盒子碰撞器都是用于較規則的物體上,恰好将所作用的對象的主要部分包裹住。是以,适當的使用該碰撞器可以減少實體計算,提高性能。
球體碰撞器——spherecollider
球體碰撞器是一個基本的球形碰撞器原型,在三維上可以均等地調節大小,但不能隻改變某一維。适合用于落石、乒乓球、彈球等。
膠囊碰撞器——capsulecollider
膠囊碰撞器由一個圓柱體連接配接兩個半球體組成,是一個膠囊狀碰撞器原型。膠囊碰撞器的半徑和高度都可以單獨調節。可用于角色控制器或者和其他碰撞器結合用于不規則的形狀。
網格碰撞器——meshcollider
網格碰撞器利用一個網格資源并在其上建構碰撞器。對于複雜網狀模型上的碰撞檢測,它要比應用原型碰撞器精确的多。其通過附加在遊戲對象上的網格建構碰撞效果,并嚴格按照所附加對象的transform屬性來設定其位置和大小比例。
車輪碰撞器——wheelcollider
車輪碰撞器是一個特殊的地面車輛碰撞器。其具有内置的碰撞檢測、車輪實體引擎和一個基于滑動的輪胎摩擦模型。當然,也可以用于其他對象,但其是專門為有輪子的車輛設計的。車輪的碰撞檢測是通過自身中心向外投射一條y軸方向的射線來實作的。
車輪碰撞器将在後面的交通工具章節有更詳細的介紹和具體使用,這裡不再贅述。
地形碰撞器——terriancollider
地形碰撞器主要作用于地形與其上的物體之間的碰撞,給地形加上地形碰撞器可以防止添加了剛體屬性的對象會無限的往下落。
說明 實際開發中,常常将多種碰撞器組合來使用,這樣可以保證碰撞的真實性。
unity開發平台下,如果開發者想要對遊戲中的對象進行碰撞處理是很簡單的事情,對于某個遊戲對象,隻需要對其附加上碰撞器即可實作。在unity中,碰撞器作為遊戲對象的一個元件,可以被随意地添加或者删除。下面将介紹碰撞器的添加方式。
1.碰撞器的基本添加方法
在這裡僅僅介紹基本碰撞器的使用。對于某個物體,如果隻是要求起到簡單的碰撞效果,那麼隻要單純地附加碰撞器即可,具體的步驟如下。
(1)首先建立一個立方體對象,按照gameobject→createother→cube順序完成建立,如圖6-22所示。
(2)在遊戲組成對象清單中,找到第(1)步建立的立方體對象,選中此對象。在屬性檢視器中看到此立方體的所有屬性,注意到其有一個名為boxcollider的元件,這就是所謂的碰撞器,如圖6-23所示。
(3)可以在“boxcollider”處滑鼠右鍵單擊,在彈出的清單中選擇“remove component”選項,通過此操作可以去除已經包含在遊戲對象中的碰撞器,如圖6-24所示。
(4)在立方體對象選中狀态下,單擊菜單欄中的“component”選項。在彈出的菜單中選擇“physics”,在彈出的菜單中選擇“box collider”,通過此操作為目前的立方體對象附加了碰撞器,如圖6-25所示。

一般情況下,隻能直接為對象指定一個碰撞器,另外指定的碰撞器會替換目前的碰撞器,如果将要替換的碰撞器和目前的碰撞器是同一種類的,則提示不能完成操作。
2.碰撞器的組合使用
在基礎項目的開發中,碰撞器的附加是很簡單的,在前面的内容中已經進行了講解。在某些場合中,由于unity内建的碰撞器都是規則的形狀類型,如果需要對一些非規則形狀的物體進行碰撞事件處理,就讓人有些手足無措,在這部分将為解決此類問題提供一種最适合的方案。
該方案的具體步驟如下。
(1)按照步驟gameobject→createother→plane建立一個平面做地面,并為其指定紋理,如圖6-26所示。
(2)按照順序gameobject→createother→capsule建立一個膠囊(capsule),将紋理圖拖曳到其上,指定好其紋理,将其放置到平面的上方,錄影機的正前方,作為碰撞器組合體的主體,如圖6-27所示。
(3)分别按照順序gameobject→createother→cube和順序gameobject→createother→sphere建立一個立方體和一個球體。将立方體和球體分别放置在前面建立的膠囊的上方和下方,相對位置如圖6-28所示。
(4)對球體進行縮放,直至膠囊把其完全掩蓋住,在屬性檢視器中修改其spherecollider元件的radius值為1.5,如圖6-29所示。将立方體進行如上操作,将其盒子碰撞器元件的size值設為(2.5,2.5,2.5),如圖6-30所示,得到效果如圖6-31所示。
(5)最後在遊戲組成對象清單中,按住ctrl鍵,同時選中立方體和球體對象,将兩個對象拖曳到膠囊對象上,形成對象的父子關系,如圖6-32所示。
(6)選中膠囊對象,按照component→physics→rigidbody為其添加剛體。單擊遊戲預覽開始按鈕,觀看效果,如圖6-33所示。
本案例的場景檔案位于随書CD光牒中源代碼/第6章目錄下的 physicsengine/assets/ scene/ collidergroup。為了簡化操作順序,本案例采用膠囊作為不規則物體的替代物,讀者可以舉一反三,對更加複雜的模型進行碰撞器拼接,以達到預期效果。
在unity開發過程中,對于某些遊戲對象,如果兩者之間進行的碰撞是毫無意義的或者不符合現實,那麼就要規避兩者之間的碰撞,在unity平台下利用了碰撞過濾的概念來解決此類問題。
碰撞過濾就是在某些物體之間不進行碰撞檢測。可以是層與層之間,也可以是兩個物體之間。這就給開發者以很大的靈活性。
1.通過代碼實作兩兩之間不進行碰撞檢測
在unity中,項目的實體環境不僅能夠通過在開發環境下進行簡單的菜單項設定,還可以通過腳本的編寫來控制設定。設定兩兩之間不進行碰撞檢測的原理是在腳本激活的時候,設定目前對象的忽略碰撞體為某一個對象。
下面以實作目前對象與兩個對象進行碰撞檢測為例說明,具體的代碼如下所示:
第1-2行為擷取不碰撞體的引用。需要在開發環境下的屬性檢視器中指定兩個對象。
第3-6行為設定目前對象不與ballpre1和ballpre2進行碰撞。
2.層與層之間的碰撞過濾
前面的内容介紹了腳本控制碰撞過濾的用法,接下來将通過一個案例講解層間碰撞過濾的具體使用方法。具體步驟如下。
(1)導入紋理圖檔資源,在資源清單中滑鼠右鍵單擊,在彈出的菜單中選擇“import new assest…”選項,如圖6-34所示,在出現的如圖6-35對話框中選擇要導入的圖檔資源,如圖6-35所示。
(2)按照gameobject→createother→plane的順序建立一個平面作為地面。并将前面導入的紋理圖拖曳到該平面上,進而為其指定紋理,如圖6-36所示。
(3)按照edit→rendersetting的順序,打開渲染設定,如圖6-37所示。
(4)通過上一步的操作,會在屬性檢視器中呈現出場景的渲染設定編輯器。在其中設定“ambient light”,如圖6-38所示,選擇ambientlight後面的屬性框,在彈出的顔色選擇框中選擇白色,如圖6-39所示。
(5)通過操作gameobject→createother→sphere建立一個球體,如圖6-40所示。
(6)在資源清單中滑鼠右鍵單擊,在彈出的菜單中選擇“create”,在彈出的菜單中選擇“material”,如圖6-41所示。在屬性檢視器中,設定maincolor為紅色,base為任意一張紋理圖,如圖6-42所示。
(7)為球體添加剛體,按照component→physics→rigidbody的順序為球體添加剛體,如圖6-43所示。
(8)添加一個層,選中球對象,單擊屬性檢視器中的layer屬性,在彈出的菜單中選擇“add layer”,如圖6-44所示。在任意一個userlayer後添加“red”,以添加層并命名為red,如圖6-45所示。
(9)再次單擊球體對象,在屬性檢視器中單擊layer,如圖6-46所示,此選擇“red”。經過此操作就為該球體制定了所在層為“red”。
(10)按照步驟(5)~步驟(7)的操作,分别建立出5個紅色球,5個藍色球,5個綠色球。
(11)按照步驟(8)~步驟(9)的操作,分别建立3個層。并将所有的紅色球指定層為red,将所有的藍色球指定為層“blue”,将所有的綠色球指定層為“green”,如圖6-47所示。
(12)設定實體管理器。按照順序edit→projectsettings→physics打開實體管理器。在屬性檢視器中會呈現實體管理器,如圖6-48所示。
(13)設定實體管理器。在實體管理器中,在layer collision matrix屬性中,去掉green行與green列的對勾,red行與red列的對勾,blue行與blue列的對勾,以設定同一個層之間不進行碰撞檢測,而不同的層之間進行碰撞檢測,如圖6-49所示。
(14)将球按照圖6-49所示的相對位置進行擺放,單擊運作檢視效果,如圖6-50所示。
本案例的場景檔案位于随書CD光牒中源代碼/第6章目錄下的 physicsengine/assets/ scene/ collisionfilter。在單擊運作按鈕後會發現圖中第1列、第3列及第5列的球沒有進行碰撞發生了疊加現象,而第2列和第4列3個球發生碰撞,這就是通過設定層間碰撞狀态達到的效果。
在unity開發過程中,開發者往往會需要碰撞體實作特殊的碰撞效果,例如籃球撞擊籃闆的效果,鉛球墜落到沙地的效果,實作這些都要使用實體材質的概念。
實體材質顧名思義就是指定了物體的實體特性。它定義了物體的彈性和摩擦因數,在實際開發過程中,開發者可以調節其屬性已達到滿意效果。
1.實體材質屬性
實體材質有多個可調屬性,這些屬性關乎着物體的彈性和摩擦因數,并且還設定了碰撞體間的摩擦和彈性混合模式,為了适應某個物體的不同方向摩擦力不同而設定的各向異性方向。各主要參數如表6-2所示。
2.實體材質的建立
作為影響物體的碰撞反應的又一重要因素,實體材質規定了物體的彈性和摩擦特性。材質的差别可能很大程度上影響物體的運動表現。實體材質的建立可以通過兩種操作實作。
(1)在菜單欄中單擊“assests”選項,會出現資源操作清單,選擇“create”選項,将會彈出建立清單,在建立清單中選擇“physics material”。即可建立出一個實體材質,同時在屬性檢視器中出現實體材質的編輯器,如圖6-51所示。
(2)在資源清單面闆下,滑鼠右鍵單擊空白處同樣會出現資源操作清單,選擇“create”選項,将會彈出建立清單,在建立清單中選擇“physics material”,即可建立出一個實體材質。同時在屬性檢視器中出現實體材質的編輯器,如圖6-52所示。
3.實體材質的設定
在開發過程中,實體材質的使用關乎到模拟現實是否成功的重要因素之一。unity為開發預留的變量使得調節物體的實體特性變得異常簡單,但是關于如何決定材質的取值,就完全靠經驗來确定了。下面介紹一些實體材質選擇的小技巧,希望對讀者有所啟發。
實體材質的設定大概需要3方面的修改,如圖6-53所示。
(1)摩擦因子的設定。
滑動摩擦因子或靜摩擦因子的取值範圍為0~1,當滑動摩擦因子或靜摩擦因子取值為0時,被此材質控制的對象将擁有冰的效果,摩擦時流暢感很強,而值為1時,受控物體就會像橡膠一樣,與其發生摩擦的物體會有不流暢感。一般來說如果對摩擦力要求不是很高,動摩擦因子或者靜摩擦因子調節為0.4即可。
(2)彈性因子的設定。
彈性因子的取值範圍同樣為0~1,當彈性因子取值為0,材質作用物體将不再擁有彈性,就像橡皮泥一樣,被一個鋼珠撞擊時将不會有任何反彈,而是直接凹陷,能量被完全損耗。當彈性因子數值為1時,材質作用的物體就像鋼珠一樣,發生碰撞為完全彈性碰撞,沒有能量的損耗。
(3)各向異性設定。
unity中采用了這一概念,使開發者可以實作這一情景:當材質所附物體向某一特定方向運動時,運動非常流暢,而像其他方向運動時會很緩慢。