Unity3D遊戲開發初探—3.初步瞭解U3D物理引擎

1、什麼是物理引擎?

  四個世紀前,物理學家牛頓發現了萬有引力,並延伸出三大牛頓定理,爲以後的物理學界的發展奠基了強大的理論基礎。牛頓有句話是這麼說的:「若是說我看得比較遠的話,那是由於我站在巨人的肩膀上。」html

  平常工做生活中,咱們寫文檔須要Word、Excel、Visio等辦公軟件,寫程序須要Visual Studio、Eclipse等各類集成開發環境、美術設計須要3dsMax、Maya、Photoshop等,正是由於有了這些強大的工具,咱們的工做效率纔會愈來愈高效。因此用記事本寫代碼、用Windows畫圖畫蒙娜麗莎什麼的,只是我的能力的體現,保留一份敬佩的心情就行了,可別真應用到實際工做中哦,老闆會瘋掉的,麼麼嗒!web

  話說不知道當年那個給牛頓帶來啓迪的蘋果,究竟是掉在了地上仍是真的掉在了牛頓的頭上,總之它就是往下掉了。運用基本的初中物理知識咱們就知道這是由於地球對蘋果施加了重力。一樣的還有在「憤怒的小鳥」中,咱們把小鳥用彈弓彈向空中以後,始終都會掉落在地面上。工具

  那麼,在Unity3D的遊戲開發中,是經過什麼機制來實現物體的物理效果的呢?咱們把目光轉移到傳說中的物理引擎上。物理引擎經過爲剛性物體(遊戲中的具體遊戲對象-GameObject)賦予真實的物理屬性的方式來模仿真實世界中的物體碰撞、跌落等反應。這裏,咱們能夠簡單地理解爲Unity3D默認幫咱們實現了一個讓遊戲對象具備真實物理對象的真實屬性(就像微軟給咱們首先鋪墊了.NET Framework,而咱們要作的就是在.NET Framework爲咱們提供的強大CLR和FCL之上編寫代碼實現具體的項目,而具體的類和對象怎麼建立、分配內存、釋放資源和封裝方法咱們通常都交給.NET Framework去處理)。例如遊戲引擎中提供了Rigid Body(剛體)組件,爲對象加入了該組件以後,遊戲對象若是判斷腳下無支撐地面就會自動往下掉,就像當年從樹上掉落砸到牛頓童鞋的蘋果同樣。性能

  簡而言之,物理引擎就是模擬真實世界中物體碰撞、跌落等反應的引擎學習

擴展:Unity的物理引擎使用的是Nvidia的PhysX,PhysX 是一套由Nvidia設計的執行復雜的物理運算的技術。有關PhysX的相關信息請參閱:http://baike.baidu.com/link?url=kESZ9LXKgp-inbAF-tdjV3OUrwh9nxWnzqWBcGuXV51ightRio9evZ2nujXCnKdxlI3flDCWTwk2jXNH67KVb_動畫

2、砸牛頓的蘋果—爲遊戲對象增長Rigid Body(剛體)

  當一個遊戲對象被賦予Rigid Body(剛體)組件以後,遊戲引擎就會對其進行物理效果模擬。同時咱們也能夠給這個對象施加各類做用力,讓它運動起來。另外若是要實現重力的效果,那麼相應的遊戲物體都必須附上剛體組件。this

  那麼,這裏咱們經過一個小例子來看看剛體組件的應用。url

  (1)在Hierarchy中Create如下游戲對象:一個Sphere,一個Direction Light,一個Plane(這裏能夠理解爲地平面)。spa

  首先將Plane的Position屬性設置爲(0,-2,0),讓Plane顯示在Sphere的下方,做爲Sphere跌落的地平面;設計

  而後將Sphere的Position屬性設置爲(0,2,0),讓Sphere顯示在Plane的上方,這樣Sphere可以顯示一個完整的跌落效果;

  最後將Main Camera的Position屬性設置爲(0,0,-5),讓主視角可以完整看到跌落效果,具體視角以下圖因此:

  (2)在Hierarchy中選中Sphere,在菜單欄中選擇Component-Physics-RigidBody,便爲Sphere增長了一個剛體組件。這下,這個Sphere便有了重力。點擊預覽按鈕,咱們能夠看到Sphere跌落的效果。(若是不增長Plane,Sphere會一直往下跌落,有興趣的朋友能夠本身試試。)

  (3)這裏,可能有的讀者會說,一個球若是談到地上應該會天然地往上彈,彈一會以後纔會平躺在地面上。也就是說,咱們這個球不但應該具備重力,還應該具備彈力。沒事!物理引擎早就幫咱們想好了。在資源管理器中的Assets上單擊鼠標右鍵,選擇Import Package-Physic Material(也就是導入一個物料材質的包),在彈出的選擇框中選中第一項Bouncy。

  (4)在Assets中找到剛剛導入的Bouncy包,選中Bouncy並拖動到Hierarchy中的Sphere對象上,這樣就爲Sphere增長了一個彈力的物理材質。也就是說,如今咱們這個球能夠在跌落到地面以後反彈了。

  (5)這下,咱們再預覽一下,看看效果:

  (6)最後,咱們來關注一下RigidBody的幾個屬性:

  ①Mass:質量—>學過物理的同窗們都知道的吧,質量越大,慣性越大。這裏的單位能夠本身統一規定,可是官方給出的建議是場景中的物體質量最好不要相差100倍率以上。估計是防止兩個質量相差太大的物體碰撞後會產生過大的速度,從而影響遊戲性能吧。

  ②Drug:阻力(也能夠表示爲摩擦力)—>這裏指的是空氣阻力,當遊戲物體收到某個做用力的時候,這個值越大越難移動。若是設置成無限的話,物體會當即中止移動。PS:上面那個Demo裏邊我就將Sphere的Drug設置爲了0.5。

  ③Angular Drag:角阻力—>一樣指的是空氣阻力,只不過是用來阻礙物體旋轉的。若是設置成無限的話,物體會當即中止旋轉。

  ④Use Gravity:是否使用重力—> 勾選了這個項,遊戲對象就會受到重力影響。

  ⑤Is Kinematic:是否動態—>勾選這個選項會使遊戲對象不受物理引擎的影響,但這不等同於沒有剛體組件。這一般用於須要用動畫控制的剛體,這樣就不會由於慣性而影響動畫了。

  另外,還有Interplate(差值類型)Collision Detection(碰撞檢測方式)以及Freeze Position/Rotation(凍結位置/旋轉),若是你有興趣,請參閱本文的參考文獻之一:《物理引擎:剛體與力》。

3、要重力更要「給力」—爲遊戲對象增長力

  相信你們都玩過Angry Birds—憤怒的小鳥吧,咱們在彈弓上將小鳥射出。根據咱們對彈弓的不一樣力度不一樣角度,小鳥飛出的距離有長有短,力量有輕有重。

  (1)在剛剛的Demo基礎上增長一個C# Script,命名爲AddForce。雙擊該腳本文件,在Update方法中寫入如下代碼:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class AddForce : MonoBehaviour
 5 {
 6 
 7     // Use this for initialization
 8     void Start()
 9     {
10 
11     }
12 
13     // Update is called once per frame
14     void Update()
15     {
16         // 判斷用戶是否按下了鼠標左鍵(0爲左鍵,1爲中建,2爲右鍵)
17         if (Input.GetMouseButtonDown(0))
18         {
19             // 參數一:朝哪一個方向使力?使多大的力?
20             // 參數二:給什麼類型的力?
21             this.gameObject.rigidbody.AddForce(Vector3.forward * 50, ForceMode.Impulse);
22         }
23     }
24 }

  (2)編寫完成以後,仍是老規矩:將腳本拖動到Sphere對象上進行綁定(也能夠說是將腳本依附於遊戲對象)。綁定完成以後,便可預覽該「給力」效果。在Sphere跌落到地平面的時候,點擊鼠標左鍵,該Sphere便迅速向前飛出。

PSrigidbody.AddForce(Vector3.forward*50,ForceMode.Impulse)表示給一個向前(up爲向上,down則爲向下,back爲向後)爲50的力->因此Sphere會彈得那麼有力!Impulse表示默示衝擊力。代碼中首先判斷用戶是否點擊了鼠標左鍵,若是點擊了則給Sphere對象增長一個向前的力。

 (3)那麼,看到這裏也許玩過不少遊戲的你會說:能不能讓小球朝着我鼠標指的方向飛呢?答案是確定的,Unity3D早就爲咱們提供了這樣的方法,讓咱們能夠「指哪打哪」!這裏就涉及到一個如何將鼠標所指示的屏幕座標轉換爲世界座標(3D遊戲中所能識別的正確座標—NGUI座標)的問題,在Unity中可使用Camera.main.ScreenToWorldPoint(new Vector3(x,y,z))方法來實現。那麼,如今就來實踐一下,修改剛剛的腳本代碼以下:

 1     void Update()
 2     {
 3         // Demo1: 判斷用戶是否按下了鼠標左鍵(0爲左鍵,1爲中建,2爲右鍵)
 4         //if (Input.GetMouseButtonDown(0))
 5         //{
 6         //    // 參數一:朝哪一個方向使力?使多大的力?
 7         //    // 參數二:給什麼類型的力?
 8         //    this.gameObject.rigidbody.AddForce(Vector3.forward * 50, ForceMode.Impulse);
 9         //}
10 
11         // Demo2:朝着用戶指定的區域爲遊戲對象給「力」
12         if (Input.GetMouseButtonDown(0))
13         {
14             Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position); 
15             Vector3 targetPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
16                 Input.mousePosition.y, screenSpace.z));
17             Vector3 dirPos = targetPos - Camera.main.transform.position;
18 
19             this.gameObject.rigidbody.AddForce(dirPos * 10, ForceMode.Impulse);
20         }
21 }

 (4)保存以後,再次預覽效果,差很少達到預期效果了,指哪打哪!

4、小結

  本篇主要介紹了物理引擎最重要的剛體組件,它讓遊戲對象一秒具備現實物理對象的重力效果。而爲對象增長衝擊力,可讓對象實現顯示對象中的衝擊效果,對於製做遊戲有着重要的做用,也是後續篇製做打箱子游戲的基礎。轉眼之間,今天就是正月十四了,後天就要回學校了,回到成都了。抓緊時間,把最後一篇也是本系列初探Unity3D的完結篇完成,也算對得起本身這一段時間的成果了,同時也謝謝各位園友給個人鼓勵!最後,再謝謝楊中科老師在上一篇博客中給個人鼓勵,謝謝如下參考文獻的做者!

參考文獻與資料

  (1)Unity3D基礎教程之組件介紹—物理引擎:http://www.narkii.com/club/thread-289321-1.html

  (2)Unity3D學習筆記(十一):物理引擎之剛體與力:http://bbs.9ria.com/thread-186986-1-1.html

  (3)傳智播客Unity3D公開課:http://net.itcast.cn/subject/Unity3D/index.html

  (4)物理引擎-百度百科:http://baike.baidu.com/link?url=ff2cOmwhuHmwPPJT5ntk7_5UxqnUdQxrJuar3iLIzvM55ZEbCW3vS2SQ6nAYX4aD

 

相關文章
相關標籤/搜索