獨立遊戲開發中的物理系統

2021-01-11 GameRes遊資網

文/王寅寅

註:本文選自機械工業出版社出版的《獨立遊戲開發:基礎、實踐與創收》一書的小節,略有改動。經出版社授權刊登於此。文末還有贈書福利哦!!!

Unity物理系統更準確的叫法應該是物理引擎(Physics Engine),該引擎是採用NVIDIA的PhysX物理引擎實現的,為避免與遊戲引擎本身的名字衝突,本書還是稱其為物理系統。所謂物理系統,是指在遊戲對象上實現加速度、碰撞、重力、摩擦力及各種外力作用的一系列功能集合。Unity物理系統又分為2D和3D兩種類型,兩者在使用上大體相似,主要區別是3D物理系統多了一個維度。

Unity物理系統沒有總開關,只要在遊戲對象上附加並正確設置了物理組件(如Rigidbody、Collider、Joint、Effector等組件),即使用了物理系統功能。下面我們繼續開發案例遊戲,並基於物理系統實現主角的移動、跳躍、自由落體及更複雜的碰撞檢測等功能。

遊戲對象調整

對於Road,我們需要將其調整為一個有一定距離且主角可以站立的路面。首先將Road的Sprite Renderer組件Draw Mode屬性選擇為Tiled(在該屬性下,圖像會根據遊戲對象尺寸自動填充,就像連續的瓦片一樣),然後在場景中拖曳Road的左右邊框(需要確保工具欄中的變換工具為Rect Tool狀態),適當增大其寬度後即可得到一個連續的路面。接下來調整碰撞器範圍,在Box Collider 2D組件中單擊Edit Collider按鈕後,碰撞器範圍即進入可編輯狀態,調整完後再次單擊Edit Collider按鈕即可。我們還需要取消碰撞器的Is Trigger屬性,以保證主角與路面的碰撞不可穿透,此時儘管Road並未附加Rigidbody 2D組件,但它相當於一個Static狀態的剛體。另外,之前的Road腳本已經不適用了,我們將其對應腳本組件從檢視窗口移除,並將該腳本文件從項目窗口刪除即可。如圖1和圖2所示:圖1展示了檢視窗口中Road的相關組件情況,標註框中為相關的調整項;圖2展示了Road在場景視圖中的情況,注意其碰撞器範圍是一個極細的矩形綠色框(圖中可能不容易看出來,請讀者結合實際操作查看),我們將該範圍上邊框調整在Road高度二分之一的位置,對應馬路中央,也是遊戲角色的水平落腳點。

圖1 Road遊戲對象相關組件情況

圖2 調整後的Road遊戲對象

註:在圖1中,有一個三角形警告符號,其內容提示我們:當前本Sprite圖像資源的導入設置可能會造成Tiled模式下的繪製錯誤。但很明顯,我們這裡並未出現繪製錯誤,筆者在實際工作中也尚未遇到過此類錯誤,忽略該警告即可。或者,可在該Sprite的圖像資源導入設置中,將Mesh Type屬性設置為Full Rect以消除該警告。

對於Player,我們需要讓其擁有重力以及合適的碰撞範圍。首先將Rigidbody 2D組件的Gravity Scale屬性設置為4,以接受該值大小的重力等級。接著重新選擇碰撞器,由於主角有一個近似圓形的外觀,因此可用圓形的Circle Collider 2D組件替換Box Collider 2D組件,並適當調整其範圍大小,如圖3所示。

圖3 調整後的Player遊戲對象

對於RoadBlock,可用類似方法調整其碰撞範圍並刪除RoadBlock腳本即可,具體步驟這裡不再贅述。

渲染順序修正

我們先運行遊戲,可以看到主角會因重力向路面下落,最終被錯誤地顯示在馬路後面,如圖4所示。要修正此問題,我們需要了解下Sprite Renderer組件的Sorting Layer與Order in Layer屬性:Sorting Layer屬性中可添加一系列特定名稱的排序分組,Unity將按照組順序依次渲染其中的Sprite;當多個Sprite同屬一個Sorting Layer分組時,則可通過Order in Layer屬性的值大小來決定它們的渲染順序。

值得注意的是,Soring Layer與Layer雖然只差一個單詞,但在Unity中它們是兩個不同的概念,可閱讀書中第5章中有關Layer的簡要介紹。另外讀者應知曉,Sprite Renderer組件功能不屬於物理系統功能。

下面,我們開始調整Sorting Layer與Order in Layer。首先,在Sorting Layer中添加一個Player分組:任意選擇一個遊戲對象,在檢視窗口中單擊Sorting Layer屬性右側的Default按鈕,並在展開的下拉列表中選擇Add Sorting Layer選項,即可打開標籤與層的有關設置,其中,Sorting Layers欄下默認僅有一個Default分組,右下角的加減號(「+ -」)可增減分組,拖曳左側的等號(「=」)則可調整組順序,這裡我們添加一個Player分組,並保持現有順序即可。然後為Player的Sprite選擇該分組:單擊Player遊戲對象,直接將其Sorting Layer屬性右側的選項選擇為剛才添加的Player分組即可。接下來,Road與RoadBlock之間同樣需要調整渲染順序:將RoadBlock拖曳到Road上,可看到錯誤的前後關係,此時保持兩者的Sorting Layer同屬默認Default分組,我們保持Road的Order in Layer屬性為0,再將RoadBlock的Order in Layer屬性設為1,即可修正渲染順序(RoadBlock為0,Road為-1也可以)。圖5展示了調整後的運行效果。

圖4 錯誤的渲染順序

圖5 修正的渲染順序

基於物理系統的移動

這裡我們修改PlayerController腳本,將當前基於Transform組件的移動替換為基於物理系統功能的移動,如代碼1所示。

代碼1 PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour

{

// 用於引用Player的Rigidbody 2D組件

private Rigidbody2D body;

// 表示主角的移動速度

public float speed;

private void Start()

{

// 獲取Player的Rigidbody 2D組件

body = GetComponent<Rigidbody2D>();

}

private void FixedUpdate()

{

KeyboardControl();

}

private void KeyboardControl()

{

// 通過鍵盤左右鍵輸入乘以速度變量得出水平速度

float sp = speed * Input.GetAxis("Horizontal");

// 根據水平速度和應有的垂直速度影響剛體速度

body.velocity = new Vector2(sp, body.velocity.y);

}

}

上述代碼中的GetComponent是一個泛型方法,用於獲取已附加組件,尖括號內為該組件的具體類型,這裡我們獲取Player的Rigidbody 2D組件,並由body變量引用。velocity是Rigidbody 2D組件中一個屬性,代表當前剛體的移動速度,我們把一個匿名二維矢量賦值給它,即可實現剛體速度驅動遊戲對象的移動。在這個匿名二維矢量中,X維度值即左右方向鍵輸入值與speed變量的積,Y維度值則對應剛體當前在該維度應有的速度(也就是說,我們僅控制水平速度,而不直接控制垂直速度,垂直速度將由外力實現,例如,下落時由物理系統重力產生向下的速度;跳躍時由人物跳躍力產生向上的速度)。

註:對精準名詞解釋一下,velocity表示速度,speed表示速率。速度是有方向和大小的矢量,而速率是沒有方向的值。在沒有特別說明時,本書把兩者都稱為速度。

基於物理系統的跳躍與碰撞

我們繼續編寫PlayerController腳本代碼,為主角添加跳躍能力,並使用更複雜的碰撞檢測來判定其是否站立在地面上,如代碼2所示。

代碼2 PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour

{

// 用於引用Player的Rigidbody 2D組件

private Rigidbody2D body;

// 表示主角的移動速度

public float speed;

private void Start()

{

// 獲取Player的Rigidbody 2D組件

body = GetComponent<Rigidbody2D>();

}

private void FixedUpdate()

{

KeyboardControl();

}

private void KeyboardControl()

{

// 通過鍵盤左右鍵輸入乘以速度變量得出水平速度

float sp = speed * Input.GetAxis("Horizontal");

// 根據水平速度和應有的垂直速度影響剛體速度

body.velocity = new Vector2(sp, body.velocity.y);

}

}

在上述代碼中,我們新增了onGround與jumpPower變量,並使用了OnCollisionStay2D與OnCollisionExit2D方法。onGround變量是一個布爾值,用於說明主角是否站立在地面上(或其他可站立物體上),當該值為真時,我們使用GetAxis("Vertical")獲取上下方向鍵輸入值,並在輸入值大於0時(向上的方向)調用AddForce方法在剛體上增加一個瞬時的力,該力是一個匿名二維矢量,作為參數傳遞給AddForce方法,我們這裡只需要一個向上的力以產生向上的速度,因此該二維矢量的X維度值設為0,Y維度值則設為代表跳躍力大小的jumpPower變量。

OnCollisionStay2D方法會在Player始終與碰撞對象接觸時連續執行,我們使用它檢測主角是否站立在地面上,其中,contactCount屬性保存了Player與某個碰撞對象之間碰撞點的數量(多數情況下為1),我們用cnum變量保存該數量,並結合for循環與GetContact方法遍歷所有的碰撞點;contact變量則用於依次保存遍歷結果,每一個碰撞點都有一個normal屬性,該屬性是一個法線向量(這裡該向量是一個長度為1,並與Player碰撞點切線垂直的二維向量),當該向量Y維度值為1時,Player的碰撞點必然在正下方,即站立在地面上。這裡我們將該值的判定標準設為0.8,以考慮碰撞點稍稍偏離正下方的情況。OnCollisionExit2D方法會在Player脫離任意碰撞時執行,我們直接在其中將onGround變量賦值為假,即說明Player處於懸空狀態。

若此時運行遊戲,主角將會以滾動方式移動,這不是我們想要的效果。可在Rigidbody 2D組件中展開Constraints選項並勾選Freeze Rotation Z屬性以解決此問題,如圖6所示。最後在檢視窗口的Player Controller腳本組件中,為Speed與Jump Power屬性分別設定一個合適的值(這裡我們設定為3和150),即可運行遊戲測試最終效果。

圖6 在Rigidbody 2D組件中鎖定Z軸旋轉

相關焦點

  • 專注爆破40年——遊戲開發中的破碎系統
    程序:在真實世界裡,物體受到衝擊會破裂成若干小塊,在遊戲中,這種破碎效果是由物理引擎中的破碎系統實現的。遊戲物理引擎會模擬物體(剛體 RigidBody)的撞擊,當撞擊發生時,物理引擎計算出撞擊的位置和衝量(作用在物體上的力在時間上的累積),將信息交給破碎系統,破碎系統判定是否需要破碎,如何破碎,如果需要,就將剛體切割和分解成若干合適的碎片,切割後由物理引擎繼續控制碎片,模擬碎片在真實世界的運動。
  • 獨立遊戲開發是如何讓我進退兩難的?
    將demo改成獨立遊戲的決定做的太草率了。其實無論在何種狀況下,如果打算做獨立遊戲,還是應該冷靜下來,認真考慮一下的。現在回過頭來看,更恰當的方式應該是,像大家廣泛建議的那樣:在開始動手做之前,先完成一個事無巨細的設定文檔。
  • 遊戲在雲、交互在端 瓏微系統讓遊戲上雲更簡單
    毫秒響應 無縫支持差異化終端瓏微系統推出C.Game雲遊戲平臺以英特爾至強 可擴展處理器為算力引擎,為雲遊戲場景及應用提供一站式服務,利用瓏微系統硬體平臺模塊化、主機無盤化、數據集中存儲、顯卡池化等優勢,實現硬體多通道獨立加速、毫秒級超低延時及極致圖像壓縮,打造超低延時、超低帶寬、超高品質的雲遊戲體驗。
  • 主機平臺獨立遊戲開發浪潮來襲,用一個機遇填補兩個空白
    獨立遊戲的熱潮興起於新世紀頭十年的後半段,起初主要在有車庫研發傳統的歐美地區,在開發傳播便利的PC平臺上,一定程度上和商業環境成熟的遊戲機平臺脫鉤。如果說製作獨立遊戲始終是非營利性的,出於個人興趣的行為,那也就只能形成一個穩定的小圈子,規模和影響力都難以成長。在新時代,獨立遊戲的範疇也在不斷拓展。現代的遊戲開發規模,費用已經相當巨大,甚至到了影響行業發展的程度。從業人員開始抱怨遊戲本身越來越單調無聊,續作成群而原創作品難以上馬面世。
  • 開發者自述:獨立小遊戲開發歷程分享
    參加 GGJ 全球 48 小時極限開發大賽中我獨立製作的作品。 當時做完大家都說還不錯,加上我一心想賺錢。。。於是我萌生出了商業化的想法,當然到現在為止還沒上架。
  • 編程貓Kitten物理引擎開發小遊戲《夢幻灌籃高手》
    一、創作緣由在很早以前,我曾經使用微軟的C#+Silverlight 2+Farseer物理引擎編寫過一個投籃小遊戲,而如今正使用Scratch開發遊戲教學軟體,那麼能否也使用少兒編程工具重新實現一款投籃小遊戲呢?因為Scratch本身並沒有提供物理引擎,所以有了兩個想法。
  • 從遊戲模組到獨立遊戲的轉變——《反恐精英》系列
    與JessCliffe開發。官方帶有13個關卡內容的遊戲劇情,每個劇情各自獨立,玩家將扮演7種國際反恐小組,完成反恐任務。地點覆蓋全世界。單人遊戲劇情的進入方法獨立於遊戲本體,需要使用菜單「遊戲更改」才能進入。《反恐精英:零點行動》的單人遊戲有Valve另一款遊戲《半條命》的氣息,兩款遊戲在內容上幾乎只有世界觀的差別,而在界面,動作上更為成熟。
  • 墨爾本獨立團隊開發遊戲《終點咖啡館》將推出中文版
    、發行工作室椰島遊戲宣布取得由墨爾本的獨立遊戲工作室 Route59 製作的冒險遊戲《終點咖啡館(Necrobarista)》,並預訂 2018 年推出中文版。   本作由 Route59 工作室開發,這是一間由亞裔組成的遊戲開發公司,成員有陳宣佑(Kevin Chen)、柳喬(Joe Liu)、Ngoc Vu 以及 Justin Petersen;陳宣佑專門創作結合遊戲、電子小說與日式動畫的敘事遊戲
  • 偵探潛行遊戲《疑雲重重(Shadows of Doubt)》由一人獨立開發 全城...
    第一人稱偵探潛行遊戲《疑雲重重(Shadows of Doubt)》是由Cole Jefferies一人獨立開發,目前這款遊戲一正處於Alpha測試階段,這位開發者也展示了20分鐘的遊戲片段,一起來看看。
  • 玩家推薦精品獨立遊戲(3)_遊俠網 Ali213.net
    機械迷城  由獨立開發小組Amanita Design設計製作的最新作品《Machinarium》PC版發售日定於09年10月16日。此作堪稱以獨特的水墨風格展現給玩家的是一款冒險解謎遊戲,值得期待。快樂的時光總是短暫的,好玩的遊戲也一樣。遊戲關卡有點少,通關後覺得不夠過癮,期待以後會推出後續的關卡!  毫不誇張的說,可以算是近幾年少見的原創遊戲。原創的遊戲模式,獨特的畫面,動聽的音樂,很完整的一款獨立遊戲,相信它能帶給你樂趣。  物理好的人玩起來可能會容易一點吧。
  • 遊戲廠商常吹的遊戲引擎究竟是什麼?遊戲開發背後的秘密大公開
    其實在計算機科學領域,"引擎"這一詞代表著一種系統,用於管理各種組件的輸入及輸出,例如人們常說的"搜尋引擎"中就有提取、過濾、組織、處理等等……這些個別的組件在運作,而透過引擎這個系統的管理,才能像流水線般快速地找出你想要搜尋的玩意。
  • 獨立遊戲的路這麼難,為什麼你還在做獨立遊戲?
    對於小型遊戲工作室來說,遊戲開發過程中的諸多問題還是難以避免的,像是資金問題、工期緊張等問題。原定於16年發布的《十三機兵防衛圈》也是一直延遲到了19年。但是,就像「遊戲之神」宮本茂說過的那樣,「延期的遊戲最終會變好,但趕工的遊戲永遠是壞的。」
  • 韓國獨立遊戲《紛爭終結者》開啟搶先體驗 支持簡中
    近日,由6個韓國人做的獨立戰旗遊戲《紛爭終結者: 被遺棄的孩子們》在Steam開啟搶先體驗,遊戲支持簡中,感興趣的玩家可以關注一下。  《紛爭終結者: 被遺棄的孩子們》由韓國獨立遊戲工作室Dandylion開發,遊戲講述了在架空歷史下,一群青年組成平民團體「紛爭終結者」(Troubleshooter)打擊犯罪的故事。
  • 獨立遊戲,從這裡起步
    僅僅是簡單容易上手,不足以讓Flash遊戲成為「遺產」。就如同非物質文化遺產一般,它總要有一些特別的貢獻。作為一種視覺呈現的載體,Flash遊戲最大的成就或許是孵化了一個真正的遊戲研發生態系統——獨立遊戲。
  • 247 Game Studio 攜多款獨立遊戲亮相CJ
    作為長期植根於微軟生態的 247 科技,旗下 247 Game Studio 攜多款代理的獨立遊戲亮相 ChinaJoy 微軟展臺。這些精彩且多樣化的獨立遊戲作品,將呈現屬於未來遊戲行業、遊戲市場,以及最終遊戲玩法的豐富可能性。正如 247 科技 CEO 張曉非表示:「我們一直在推動遊戲業的發展,把玩家從幫助玩家從遊戲過程中獲得更多樂趣。」
  • 編程遊戲開發:如何開發製作一款遊戲?你需要做哪些準備?
    關於遊戲開發,需要對從一開始到最後開發一款遊戲的一般過程有所了解。一般不是一個完整的,一步一步的指導完成的結果。你還需要自己找出相當多的東西才能有一個遊戲。
  • 獨立物理模擬遊戲《拆遷》Teardown遊戲專題站上線
    中文稱號:拆遷英文稱號:Teardown建造公司:Tuxedo Labs刊行公司:Tuxedo Labs遊戲範例:模仿謀劃SIM遊戲領域:PC>遊戲說話:英文出售日期:2020-12-21點擊進來遊俠網《拆遷》專題站遊戲說明《拆遷(Teardown)》是一款行將登岸Steam的物理模仿遊戲,此中的物體都由體素(3D版像素)組成,所以能更好地模仿破裂、形變等物理結果
  • 《幻影沙塵》重啟開發商倒閉 不過遊戲仍在開發中
    《幻影沙塵》重啟開發商倒閉 不過遊戲仍在開發中 時間:2015-02-18 09:08:40 來源:3DM新聞組-skylark
  • 系統設計和開發以運動為基礎的體感遊戲,有助於提升學生的思維能力
    摘要:過去幾年,學生們對於製作數字遊戲的興趣日益增強,並藉此增強思維能力。一些研究檢驗了製作數字遊戲的影響,結果十分樂觀,在促進發展21世紀所需技能上尤其如此。然而,許多學生似乎難以更加深入地理解遊戲開發的過程。此外,他們往往還難以將各個學科(主要是數學和物理)中的概念有意識地運用到遊戲製作中來,也難以在製作高級編程指令時運用這些概念。
  • 中文站前版主獨立開發的遊戲發布了《中世紀君主》
    小編註:《中世紀君主》是一款由騎馬與砍殺的資深騎友(也是一位非常優秀的前騎砍中文站論壇版主)耗時一年,完全靠個人獨立製作的以歐洲中世紀為歷史背景的國產原創模擬養成遊戲。這款遊戲已於2020年1月2日在Steam上架,目前售價僅30元人民幣。