3D定點(diǎn)物理引擎實(shí)戰(zhàn)系列之 BEPUphysicsint定點(diǎn)數(shù)3D物理引擎使用

上一節(jié)給大家介紹了BEPUphysicsint的一些基本的情況,這節(jié)課我們來(lái)介紹它的基本使用,本節(jié)主要從以下5個(gè)方面來(lái)介紹:

(1) 創(chuàng)建一個(gè)物理世界Space蟹漓,并開啟模擬迭代;

(2) 添加一個(gè)物理物體Entity到世界;

(3) 物理引擎的基本處理與操作使用;

(4) 添加靜態(tài)的Mesh形狀的物理物體;

(5) 處理物理事件;

對(duì)惹晋柱,這里有一個(gè)游戲開發(fā)交流小組曙蒸,希望大家可以點(diǎn)擊進(jìn)來(lái)一起交流一下開發(fā)經(jīng)驗(yàn)呀

創(chuàng)建一個(gè)物理世界

在游戲中使用BEPUphysicsint物理引擎,首先要?jiǎng)?chuàng)建一個(gè)物理世界Space(物理空間)鲤屡。所有的物理的物體都加入到這個(gè)物理世界中統(tǒng)一的模擬與迭代老充。在游戲框架初始化的位置进倍,我們來(lái)創(chuàng)建物理世界,代碼很簡(jiǎn)單:

space = new Space();

世界創(chuàng)建出來(lái)后土至,物理的物體就有地方可以放了。世界創(chuàng)建后猾昆,需要模擬迭代物理計(jì)算陶因,所以在游戲框架中的某個(gè)Update/FixedUpdate的地方來(lái)迭代物理世界,代碼很簡(jiǎn)單,調(diào)用space的Update接口就可以了垂蜗。如下:

space.Update();

這個(gè)代碼被調(diào)用后楷扬,物理引擎就開始迭代計(jì)算里面的物理物體了。

物理世界里面的重力默認(rèn)是(0, 0, 0), 我們可以通過(guò)接口來(lái)設(shè)置物理世界的重力,代碼如下:

space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0);

創(chuàng)建物理Entity到物理世界

物理世界創(chuàng)建出來(lái)后贴见,目前世界是空的烘苹,沒(méi)有任何物理Enity,接下來(lái)就是往物理世界里面放一些物理的Entity片部。你可以創(chuàng)建各種不同的物理Entity類型包括有: 長(zhǎng)方體(Box)镣衡、圓柱體(Cylinder)、球體(Sphere)吞琐、膠囊(Capsules)和其它可以在BepupPhysics中找到的實(shí)體類型捆探。你可以右鍵”轉(zhuǎn)到定義”去查看可以支持的類型來(lái)解決問(wèn)題。

所有的物理Entity分為兩種: Dynamic Entity與Kinematic Entity站粟。Dynamic Entity按照物理的方式來(lái)進(jìn)行運(yùn)動(dòng)模擬與迭代包括: 下落, 碰撞,反彈,滑動(dòng)等黍图。Kinematic Entity類似于動(dòng)力學(xué)實(shí)體,但可以認(rèn)為具有無(wú)限質(zhì)量,除非明確的設(shè)置,否則不會(huì)因?yàn)槿魏蔚呐鲎埠拖嗷プ饔昧Χ淖兾锢淼乃俣?大小+方向)奴烙。Kinematic Entity可以理解為是一個(gè)可以推動(dòng)的物體助被,如果兩個(gè)這樣的物體相遇,那么他們會(huì)相互的穿越而過(guò)切诀。

在構(gòu)建Dynamic Entity與Kinematic Entity的時(shí)候揩环,它們構(gòu)建的區(qū)別就在最后一個(gè)參數(shù), Dynamic Entity有物體質(zhì)量mass,而Kinematic Entity沒(méi)有質(zhì)量。當(dāng)Entity構(gòu)建出來(lái)以后幅虑,也可以調(diào)用接口BecomeKinematic/BecomeDynamic 來(lái)改變Entity的類型丰滑。

Kinematic Entity可以在游戲中用于靜態(tài)物體與結(jié)構(gòu)形狀物體(如:地形),我們可以創(chuàng)建一個(gè)Box的Kinematic Entity,來(lái)作為我們的地面Ground,代碼如下:

Box ground = new Box(Vector3.Zero, 30, 1, 30);

第一個(gè)參數(shù)是物理地面在物理世界space中的位置倒庵。后面三個(gè)參數(shù)分別為Box物體的長(zhǎng)褒墨,高炫刷,寬。創(chuàng)建出來(lái)后郁妈,我們把地面加入到物理世界進(jìn)行迭代模擬浑玛,代碼如下:

space.Add(ground);

接下來(lái)我們?cè)偻孛嫔戏乓恍〥ynamic Entity,用來(lái)模擬動(dòng)態(tài)的物體,代碼如下:

space.Add(new Box(new Vector3(0, 4, 0), 1, 1, 1, 1)); space.Add(new Box(new Vector3(0, 8, 0), 1, 1, 1, 1)); space.Add(new Box(new Vector3(0, 12, 0), 1, 1, 1, 1));

由于Dynamic Entity必須要有質(zhì)量mass,所以最后一個(gè)參數(shù)就是質(zhì)量mass噩咪。當(dāng)調(diào)用構(gòu)造函數(shù)時(shí)顾彰,如果有質(zhì)量就會(huì)把物理的Entity認(rèn)為是Dynamic,否則就是Kinematic。

我們構(gòu)建出來(lái)物理世界+物理Entity以后胃碾,我們的物理世界就會(huì)在重力等作用下迭代出當(dāng)前物理世界最新的狀態(tài)與變化涨享。

物理引擎的基本處理與操作使用

我們創(chuàng)建出物理世界,往里面加入物體Entity后仆百,物理世界迭代起來(lái)了灰伟,但是對(duì)于畫面來(lái)說(shuō)什么都看不見,接下來(lái)我們就是要同步儒旬。如何把物理引擎能和”圖像視覺(jué)”同步呢?其實(shí)就是在Update里面帖族,實(shí)時(shí)的把物理Entity里面的postion, rotation, scale同步到游戲物體中的Transform組件里面栈源。獲取物理Entity的位置代碼如下:

Matrix worldMatrix = Transform * entity.WorldTransform;

這里要注意,物理的中心最好要與圖像節(jié)點(diǎn)節(jié)點(diǎn)的中心保持一致竖般,這樣我們就可以獲得Entity的Transform數(shù)據(jù)同步到wolrdMatrix甚垦。

當(dāng)我們的圖像同步做好以后,我們只要控制物理Entity,就能帶動(dòng)圖像節(jié)點(diǎn)移動(dòng)了涣雕,我們來(lái)看下如何給物理Entity一個(gè)線性速度代碼如下:

toAdd.LinearVelocity = Entity.Forward * 10;

上面的代碼為給物理Entity一個(gè)方向?yàn)閒orward,大小為10的線性速度,這樣物理世界就會(huì)模擬迭代entiy變化艰亮,同時(shí)update同步給圖像節(jié)點(diǎn),這樣圖像節(jié)點(diǎn)就飛出去了挣郭。

Mesh形狀的物理Entity

在很多物理Entity中,有一個(gè)比較特殊迄埃,叫做StaticMesh, 一般我們用來(lái)模擬復(fù)雜物理環(huán)境,它的本質(zhì)就是根據(jù)3D物體的Mesh來(lái)創(chuàng)建一個(gè)物理Entity出來(lái)兑障,形狀和3D Mesh一樣侄非。代碼如下:

Vector3[] vertices;int[] indices;ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);var mesh = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(0, -40, 0)));space.Add(mesh);

基于游戲引擎,編寫一個(gè)ModelDataExtractor, 能從模型里面讀出定點(diǎn)數(shù)據(jù)與面的索引,根據(jù)定點(diǎn)與面的索引流译,來(lái)創(chuàng)建出和Mesh形狀一樣的物理Entity逞怨。所以整合到Unity引擎的時(shí)候,我們只要編寫對(duì)應(yīng)的ModelDataExtractor功能既可以很方便的創(chuàng)建出來(lái)StaticMesh 物理Entity了福澡。一般我們把StaticMesh用于部署復(fù)雜物理環(huán)境叠赦。

物理Entity的事件處理

游戲整合好物理引擎以后,接下來(lái)要面對(duì)的就是處理物理事件革砸。物理事件包括了觸發(fā)與碰撞除秀。BEPUphsicsint的物理事件都可以在名字空間: BEPUphysics.Events中找到糯累。為了監(jiān)聽到對(duì)應(yīng)的事件,我們只需要在物理Entity上添加事件回調(diào)就可以了鳞仙,比如寇蚊,我們要添加InitialCollisionDetected事件,代碼如下:

deleterBox.EventManager.InitialCollisionDetected += HandleCollision;

以上面的平面+Box為例,當(dāng)一個(gè)Dynamic Box掉下來(lái)棍好,碰到地面Kinematic后仗岸,我們就可以這樣來(lái)寫回調(diào)函數(shù),代碼如下:

void HandleCollision(EntityCollidable sender, Collidable other, CollidablePairHandler pair){
    var otherEntityInformation = other as EntityCollidable;

    if (otherEntityInformation != null) {
        space.Remove(otherEntityInformation.Entity);
        Components.Remove((EntityModel)otherEntityInformation.Entity.Tag);
    }}

第一個(gè)參數(shù)sender就是碰撞實(shí)體,本例中就是deleterBox, 第二個(gè)參數(shù)other借笙,于碰撞實(shí)體發(fā)生碰撞的其它物體信息扒怖。第三個(gè)參數(shù)pair, 記錄了兩個(gè)碰撞實(shí)體的碰撞信息,我們可以獲取。

今天的BEPUphysicsint的基本使用和概念就分享到這里业稼,關(guān)注我們盗痒,學(xué)習(xí)如果在Unity中構(gòu)建基于確定性的3D物理引擎BEPUphysicsint。

下節(jié)預(yù)告: 基于BEPUphysicsint整合到Unity項(xiàng)目實(shí)戰(zhàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末低散,一起剝皮案震驚了整個(gè)濱河市俯邓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熔号,老刑警劉巖稽鞭,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異引镊,居然都是意外死亡朦蕴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門弟头,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吩抓,“玉大人,你說(shuō)我怎么就攤上這事赴恨≌钊ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵嘱支,是天一觀的道長(zhǎng)蚓胸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)除师,這世上最難降的妖魔是什么沛膳? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮汛聚,結(jié)果婚禮上锹安,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好叹哭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布忍宋。 她就那樣靜靜地躺著,像睡著了一般风罩。 火紅的嫁衣襯著肌膚如雪糠排。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天超升,我揣著相機(jī)與錄音入宦,去河邊找鬼。 笑死室琢,一個(gè)胖子當(dāng)著我的面吹牛乾闰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盈滴,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涯肩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了巢钓?” 一聲冷哼從身側(cè)響起病苗,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎症汹,沒(méi)想到半個(gè)月后铅乡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烈菌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了花履。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芽世。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖诡壁,靈堂內(nèi)的尸體忽然破棺而出济瓢,到底是詐尸還是另有隱情,我是刑警寧澤妹卿,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布旺矾,位于F島的核電站,受9級(jí)特大地震影響夺克,放射性物質(zhì)發(fā)生泄漏箕宙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一铺纽、第九天 我趴在偏房一處隱蔽的房頂上張望柬帕。 院中可真熱鬧,春花似錦、人聲如沸陷寝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凤跑。三九已至爆安,卻和暖如春宛篇,著一層夾襖步出監(jiān)牢的瞬間铣耘,已是汗流浹背蔓罚。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工丽猬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晌梨,地道東北人眷蚓。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓较鼓,卻偏偏與公主長(zhǎng)得像晋渺,于是被迫代替她去往敵國(guó)和親鲤看。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缘揪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容