Unity物理系統由淺入深第一節:Unity 物理系統基礎與應用

Unity物理系統由淺入深第一節:Unity 物理系統基礎與應用
Unity物理系統由淺入深第二節:物理系統高級特性與優化
Unity物理系統由淺入深第三節:物理引擎底層原理剖析
Unity物理系統由淺入深第四節:物理約束求解與穩定性

Unity 引擎內置了一套強大且易用的物理系統,它基于 NVIDIA 的 PhysX 物理引擎。這個系統能讓你在游戲中模擬真實的物理效果,比如重力、碰撞、摩擦、彈跳等,極大地提升游戲的沉浸感和交互性。本篇教程將帶你了解 Unity 物理系統的核心組件和常用 API,讓你能夠快速地在項目中應用物理效果。


1. Rigidbody(剛體)組件:賦予物體物理屬性

在 Unity 中,任何想要受到物理系統影響的 GameObject 都必須附加一個 Rigidbody 組件。Rigidbody 賦予了 GameObject 質量、速度、角速度等物理屬性,并使其能夠響應重力、力、碰撞等物理事件。

核心屬性:
  • Mass (質量):物體的質量,以千克(kg)為單位。質量越大,受到相同力的作用時加速度越小。
  • Drag (阻力):線性阻力,模擬空氣阻力或液體阻力。值越大,物體運動減速越快。
  • Angular Drag (角阻力):角阻力,模擬物體旋轉時的阻力。值越大,物體旋轉減速越快。
  • Use Gravity (使用重力):勾選后,物體將受到 Unity 全局重力設置的影響(默認向下)。
  • Is Kinematic (是否運動學)
    • 如果勾選,Rigidbody 將不再受物理引擎控制,你需要通過代碼(Transform.positionTransform.rotation)手動控制它的位置和旋轉。運動學剛體通常用于門、電梯等受腳本控制的物體。
    • 重要提示: 運動學剛體不會受到碰撞影響而移動或旋轉,但它仍然可以影響其他非運動學剛體,并且會觸發碰撞回調。
  • Collision Detection (碰撞檢測模式)
    • Discrete (離散):默認模式,在每個物理步長(Fixed Update)只檢測一次碰撞。適用于大多數情況,性能開銷低,但高速移動的物體可能會“穿透”其他物體。
    • Continuous (連續):適用于高速移動的物體,會進行更頻繁的檢測以防止穿透。性能開銷比 Discrete 高。
    • Continuous Dynamic (連續動態):適用于高速移動且相互之間都需要進行連續碰撞檢測的 Rigidbody。性能開銷最高。
  • Constraints (約束):可以凍結剛體的特定軸向上的位置或旋轉,例如,只允許物體在 X 軸上移動,或者不允許它旋轉。
常用操作:
  • Rigidbody.AddForce(Vector3 force, ForceMode mode = ForceMode.Force):給剛體施加一個力。
    • ForceMode.Force: 持續力,以物體的質量計算加速度。
    • ForceMode.Impulse: 瞬間沖量,不考慮時間,直接改變物體的速度。常用于爆炸或打擊效果。
    • ForceMode.VelocityChange: 瞬間速度變化,忽略質量。
    • ForceMode.Acceleration: 持續加速度,忽略質量。
  • Rigidbody.AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force):給剛體施加一個扭矩,使其旋轉。
  • Rigidbody.velocity: 獲取或設置剛體的線性速度。
  • Rigidbody.angularVelocity: 獲取或設置剛體的角速度。
using UnityEngine;public class BallController : MonoBehaviour
{public float moveForce = 10f;public float jumpForce = 5f;private Rigidbody rb;void Start(){rb = GetComponent<Rigidbody>();}void FixedUpdate() // 物理計算應該在 FixedUpdate 中進行{// 施加持續力,模擬移動if (Input.GetKey(KeyCode.W)){rb.AddForce(Vector3.forward * moveForce, ForceMode.Force);}if (Input.GetKey(KeyCode.S)){rb.AddForce(Vector3.back * moveForce, ForceMode.Force);}// 施加瞬間沖量,模擬跳躍if (Input.GetKeyDown(KeyCode.Space)){rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);}}
}

2. Collider(碰撞體)組件:定義物體的形狀

Collider 組件定義了 GameObject 在物理世界中的形狀,用于檢測與其他物體的碰撞。沒有 Collider 的 Rigidbody 無法與其他物體發生物理交互(除了重力)。

常見碰撞體類型:
  • Box Collider (盒碰撞體):最常用的碰撞體,適用于立方體、矩形等規則形狀。性能開銷低。
  • Sphere Collider (球碰撞體):適用于球體或近似球體的物體。性能開銷低。
  • Capsule Collider (膠囊碰撞體):適用于人物角色、圓柱體等。性能開銷低。
  • Mesh Collider (網格碰撞體)
    • 使用物體的網格數據作為碰撞形狀。
    • 優點: 可以完美匹配復雜模型的形狀。
    • 缺點: 性能開銷高,特別是對于高多邊形模型。
    • Convex (凸包) 選項:勾選后,Mesh Collider 將創建一個凸包形狀作為碰撞體。凸包的性能遠高于非凸包,并且可以與其他 Mesh Collider 發生碰撞。非凸包 Mesh Collider 只能與 Box、Sphere、Capsule 等原始碰撞體碰撞,不能與其他非凸包 Mesh Collider 碰撞。
    • 通常不建議用于移動的 Rigidbody,除非設置為 Convex。
  • Terrain Collider (地形碰撞體):專門用于 Unity 地形系統,自動與地形的形狀匹配。
核心屬性:
  • Is Trigger (是否觸發器)
    • 如果勾選,這個 Collider 將不會產生物理碰撞響應(如反彈、滑動),而是僅僅檢測到與其他 Collider 的重疊
    • 觸發器常用于檢測區域進入/離開,例如,當玩家進入一個區域時觸發劇情或打開門。
    • 兩個觸發器之間不會產生碰撞回調,除非其中一個至少帶有 Rigidbody。
    • 一個觸發器和一個非觸發器 Collider 之間的交互會觸發回調。
  • Material (物理材質):關聯一個 Physic Material(詳見下一節)。

最佳實踐: 盡量使用簡單的原始碰撞體(Box、Sphere、Capsule)組合來近似復雜模型的形狀,而不是直接使用 Mesh Collider,以獲得更好的性能。


3. Physic Material(物理材質):定義交互特性

Physic Material 是一種資源(Asset),用于定義碰撞體之間的摩擦力和彈性(彈跳)。你可以創建不同的物理材質并將其分配給 Collider 組件。

核心屬性:
  • Dynamic Friction (動態摩擦):當物體相對運動時產生的摩擦力。
  • Static Friction (靜態摩擦):當物體靜止時抵抗初始運動的摩擦力。通常應該略高于 Dynamic Friction。
  • Bounciness (彈跳):物體的彈性,0 表示完全不彈跳,1 表示完全彈性碰撞。
  • Friction Combine (摩擦組合模式)
    • Average (平均):取兩個碰撞體物理材質的摩擦力平均值。
    • Minimum (最小):取兩個碰撞體物理材質摩擦力的最小值。
    • Maximum (最大):取兩個碰撞體物理材質摩擦力的最大值。
    • Multiply (相乘):取兩個碰撞體物理材質摩擦力的乘積。
  • Bounce Combine (彈跳組合模式):同 Friction Combine,但作用于彈跳。

創建和使用:
在 Project 窗口右鍵 -> Create -> Physic Material,然后調整其屬性,并將其拖拽到 Collider 組件的 “Material” 字段上。


4. 觸發器與碰撞回調:響應物理事件

當 Rigidbody 與 Collider 發生交互時,Unity 會調用特定的回調函數。理解這些回調函數是實現游戲邏輯的關鍵。

碰撞回調 (Collision Callbacks):

適用于兩個非觸發器 Collider(至少一個帶 Rigidbody)之間的物理碰撞。

  • OnCollisionEnter(Collision collision):當物體開始與其他物體碰撞時調用一次。
    • collision 參數包含了碰撞的詳細信息,如碰撞點 (collision.contacts)、碰撞法線 (collision.contacts[0].normal)、對方的 GameObject (collision.gameObject) 和 Rigidbody (collision.rigidbody) 等。
  • OnCollisionStay(Collision collision):當物體持續與其他物體碰撞時,每物理幀調用一次。
  • OnCollisionExit(Collision collision):當物體停止與其他物體碰撞時調用一次。
觸發器回調 (Trigger Callbacks):

適用于至少有一個 Collider 設置為 Is Trigger 的情況下,檢測到物體進入/離開/停留在區域內。

  • OnTriggerEnter(Collider other):當物體開始進入觸發器區域時調用一次。
    • other 參數是進入或離開觸發器區域的 Collider。
  • OnTriggerStay(Collider other):當物體持續停留在觸發器區域內時,每物理幀調用一次。
  • OnTriggerExit(Collider other):當物體離開觸發器區域時調用一次。

重要規則:

  • 只有當一個 Collider 附加了 Rigidbody,或者它是一個 Kinematic Rigidbody 上的 Collider 時,它才能接收到碰撞/觸發器回調。
  • 注意: 如果是靜態(不帶 Rigidbody)的 Collider 之間發生碰撞,雖然物理系統會處理它們之間的交互,但不會調用任何回調函數。
using UnityEngine;public class CollisionDetector : MonoBehaviour
{// 當發生碰撞時void OnCollisionEnter(Collision collision){Debug.Log("OnCollisionEnter: " + gameObject.name + " 撞到了 " + collision.gameObject.name);// 可以在這里獲取碰撞點、法線等信息foreach (ContactPoint contact in collision.contacts){Debug.Log("碰撞點: " + contact.point + ", 法線: " + contact.normal);}}// 當進入觸發器區域時void OnTriggerEnter(Collider other){Debug.Log("OnTriggerEnter: " + gameObject.name + " 進入了觸發器區域 " + other.gameObject.name);if (other.CompareTag("Collectible")) // 假設我們有一個Tag為"Collectible"的物體{Debug.Log("拾取了物品!");Destroy(other.gameObject); // 銷毀被拾取的物品}}
}

5. 射線檢測(Raycast)與形狀檢測:非碰撞交互

除了碰撞體之間的物理交互,Unity 也提供了用于檢測特定方向或形狀是否存在物體的 API,這在很多游戲邏輯中非常有用,例如射擊游戲中的子彈檢測、角色控制器中的地面檢測等。

射線檢測 (Raycast):

從一個點發射一條射線,檢測是否擊中物體。

  • Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance)
    • origin: 射線的起點。
    • direction: 射線的方向。
    • hitInfo: 一個 RaycastHit 結構體,用于存儲擊中物體的信息(如擊中點、法線、被擊中的 Collider 和 GameObject 等)。
    • maxDistance: 射線的最大檢測距離。
  • 還可以指定 LayerMask 來過濾檢測的層級。
using UnityEngine;public class RaycastExample : MonoBehaviour
{public LayerMask hitLayer; // 設置一個層級,只檢測這個層級的物體void Update(){// 從攝像機向鼠標點擊位置發射射線if (Input.GetMouseButtonDown(0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit, 100f, hitLayer)) // 檢測最遠100米,只檢測hitLayer層的物體{Debug.Log("射線擊中了: " + hit.collider.gameObject.name + " 在位置: " + hit.point);// 可以在這里對被擊中的物體進行操作hit.collider.gameObject.GetComponent<Renderer>().material.color = Color.red;}else{Debug.Log("射線未擊中任何物體。");}}}
}
形狀檢測 (Shape Cast):

除了射線,你還可以發射一個球體、膠囊體或盒子來檢測是否與場景中的 Collider 發生重疊或碰撞。這比 Raycast 更適合檢測更大范圍的障礙物。

  • Physics.SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance, LayerMask layerMask):發射一個球體。
  • Physics.BoxCast(Vector3 center, Vector3 halfExtents, Vector3 direction, out RaycastHit hitInfo, Quaternion orientation, float maxDistance, LayerMask layerMask):發射一個盒子。
  • Physics.CapsuleCast(...):發射一個膠囊體。

這些方法與 Raycast 類似,只是將線替換成了對應的形狀,用于更精確或范圍更大的檢測。


總結

至此,你已經掌握了 Unity 物理系統的核心基礎:

  • Rigidbody 是物體參與物理模擬的必備組件。
  • Collider 定義了物體的碰撞形狀。
  • Physic Material 決定了碰撞時的摩擦和彈跳特性。
  • 碰撞回調和觸發器回調 讓你能夠響應物理事件并執行游戲邏輯。
  • 射線檢測和形狀檢測 提供了在不發生物理交互的情況下查詢物理世界的能力。

熟練運用這些基礎功能,你就能在 Unity 中構建出豐富多樣的物理交互和游戲玩法。在下一篇文章中我們將進入更深層次的探索,了解如何利用高級特性實現復雜交互,并關注性能優化,讓你的物理模擬既強大又流暢

Unity物理系統由淺入深第一節:Unity 物理系統基礎與應用
Unity物理系統由淺入深第二節:物理系統高級特性與優化
Unity物理系統由淺入深第三節:物理引擎底層原理剖析
Unity物理系統由淺入深第四節:物理約束求解與穩定性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90897.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90897.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90897.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《[系統底層攻堅] 張冬〈大話存儲終極版〉精讀計劃啟動——存儲架構原理深度拆解之旅》-系統性學習筆記(適合小白與IT工作人員)

&#x1f525; 致所有存儲技術探索者筆者近期將系統攻克存儲領域經典巨作——張冬老師編著的《大話存儲終極版》。這部近千頁的存儲系統圣經&#xff0c;以庖丁解牛的方式剖析了&#xff1a;存儲硬件底層架構、分布式存儲核心算法、超融合系統設計哲學等等。喜歡研究數據存儲或…

flutter鴻蒙版 環境配置

flutter支持開發鴻蒙,但是需要專門的flutter鴻蒙項目, Flutter鴻蒙化環境配置&#xff08;windows&#xff09;_flutter config --ohos-sdk-CSDN博客

Java 高級特性實戰:反射與動態代理在 spring 中的核心應用

在 Java 開發中&#xff0c;反射和動態代理常被視為 “高級特性”&#xff0c;它們看似抽象&#xff0c;卻支撐著 Spring、MyBatis 等主流框架的核心功能。本文結合手寫 spring 框架的實踐&#xff0c;從 “原理” 到 “落地”&#xff0c;詳解這兩個特性如何解決實際問題&…

Codeforces Round 855 (Div. 3)

A. Is It a Cat? 去重&#xff0c; 把所有字符看成大寫字符&#xff0c; 然后去重&#xff0c; 觀察最后結果是不是“MEOW” #include <bits/stdc.h> #define int long longvoid solve() {int n;std::cin >> n;std::string ans, t;std::cin >> ans;for (int…

Scrapy選擇器深度指南:CSS與XPath實戰技巧

引言&#xff1a;選擇器在爬蟲中的核心地位在現代爬蟲開發中&#xff0c;??選擇器??是數據提取的靈魂工具。根據2023年網絡爬蟲開發者調查數據顯示&#xff1a;??92%?? 的數據提取錯誤源于選擇器編寫不當熟練使用選擇器的開發效率相比新手提升 ??300%??同時掌握CSS…

Windos服務器升級MySQL版本

Windos服務器升級MySQL版本 1.備份數據庫 windows下必須以管理員身份運行命令行工具進行備份&#xff0c;如果沒有配置MySQL的環境變量&#xff0c;需要進入MySQL Server 的bin目錄輸入指令&#xff0c; mysqldump -u root -p --all-databases > backup.sql再輸入數據庫密碼…

告別頻繁登錄!Nuxt3 + TypeScript + Vue3實戰:雙Token無感刷新方案全解析

前言 在現代 Web 應用中&#xff0c;身份認證是保障系統安全的重要環節。傳統的單 Token 認證方式存在諸多不足&#xff0c;如 Token 過期后需要用戶重新登錄&#xff0c;影響用戶體驗。本文將詳細介紹如何在 Nuxt3 TypeScript Vue3 項目中實現無感刷新 Token 機制&#xff…

Linux——Redis

目錄 一、Redis概念 1.1 Redis定義 1.2 Redis的特點 1.3 Redis的用途 1.4 Redis與其他數據庫的對比 二、Redis數據庫 三、Redis五個基本類型 3.1 字符串 3.2 列表(list) ——可以有相同的值 3.3 集合(set) ——值不能重復 3.4 哈希(hash) ——類似于Map集合 3.5 有序…

【AI大模型】部署優化量化:INT8壓縮模型

INT8&#xff08;8位整數&#xff09;量化是AI大模型部署中最激進的壓縮技術&#xff0c;通過將模型權重和激活值從FP32降至INT8&#xff08;-128&#xff5e;127整數&#xff09;&#xff0c;實現4倍內存壓縮2-4倍推理加速&#xff0c;是邊緣計算和高并發服務的核心優化手段。…

LFU 緩存

題目鏈接 LFU 緩存 題目描述 注意點 1 < capacity < 10^40 < key < 10^50 < value < 10^9對緩存中的鍵執行 get 或 put 操作&#xff0c;使用計數器的值將會遞增當緩存達到其容量 capacity 時&#xff0c;則應該在插入新項之前&#xff0c;移除最不經常使…

檢查輸入有效性(指針是否為NULL)和檢查字符串長度是否為0

檢查輸入有效性&#xff08;指針是否為NULL&#xff09;和檢查字符串長度是否為0 這兩個檢查針對的是完全不同的邊界情況&#xff0c;都是必要的防御性編程措施&#xff1a; 1. 空指針檢查 if(!src) 目的&#xff1a;防止解引用空指針場景&#xff1a;當調用者傳入 NULL 時風險…

Apache POI 的 HSSFWorkbook、SXSSFWorkbook和XSSFWorkbook三者的區別

HSSFWorkbook 專用于處理Excel 97-2003&#xff08;.xls&#xff09;格式的二進制文件。基于純Java實現&#xff0c;所有數據存儲在內存中&#xff0c;適合小規模數據&#xff08;通常不超過萬行&#xff09;。內存占用較高&#xff0c;但功能完整&#xff0c;支持所有舊版Exce…

冷凍電鏡重構的GPU加速破局:從Relion到CryoSPARC的并行重構算法

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生專屬優惠。 一、冷凍電鏡重構的算力困局 隨著單粒子冷凍電鏡&#xff08;cryo-EM&#xff09;分辨率突破…

算法學習筆記:16.哈希算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學中&#xff0c;哈希算法&#xff08;Hash Algorithm&#xff09;是一種將任意長度的輸入數據映射到固定長度輸出的技術&#xff0c;其輸出稱為哈希值&#xff08;Hash Value&#xff09;或散列值。哈希算法憑借高效的查找、插入和刪除性能&#xff0c;在數據存儲、…

16018.UE4+Airsim仿真環境搭建超級詳細

文章目錄 1 源碼下載2 下載安裝軟件2.1 安裝 UE4 軟件2.2 安裝visual studio 20223 編譯airsim源碼4 進入AirSim工程,打開工程5 UE4 工程創建5.1 下載免費場景 CityPark,并創建工程5.2 工程編譯5.2.1 將airsim 插件拷貝到 UE4工程路徑中5.2.2 修改工程配置文件5.2.3 創建c++類…

Python 實戰:構建 Git 自動化助手

在多項目協作、企業級工程管理或開源社區維護中&#xff0c;經常面臨需要同時管理數十甚至上百個 Git 倉庫的場景&#xff1a;多倉庫需要統一 pull 拉取更新定期向多個項目批量 commit 和 push自動備份 Git 項目批量拉取私有倉庫并管理密鑰為解決這類高頻、重復、機械性工作&am…

【PTA數據結構 | C語言版】出棧序列的合法性

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 給定一個最大容量為 m 的堆棧&#xff0c;將 n 個數字按 1, 2, 3, …, n 的順序入棧&#xff0c;允許按任何順序出棧&#xff0c;則哪些數字序列是不可能得到的&#xff1f;例如給定 m5、n7&#xf…

【LangGraph】create_react_agent 方法詳細解釋

create_react_agent 方法詳細解釋 create_react_agent 方法是一個在 LangGraph 中創建 React 代理的核心函數,接下來我們將一起探討這個函數的作用、參數、返回值以及工作原理。 @_convert_modifier_to_prompt def create_react_agent(model: Union[str, LanguageModelLike]…

【時間之外】塵封的智能套件復活記

目錄 塵封的獎品 初次觸網的挫敗 客服只會誘導消費 意外發現的生機 真相與反思 塵封的獎品 五年前那個蟬鳴陣陣的夏日&#xff0c;我抱著創新比賽特等獎的獎品禮盒走下領獎臺時&#xff0c;絕對想不到這份榮譽會衍生出如此曲折的故事。禮盒里靜靜躺著的智能家居套裝&…

從零開始學前端html篇1

1基本結構<!DOCTYPE html> <html><head><title>this is a good website</title></head><body><h1>hello!</h1></body> </html>運行效果如下&#xff08;編輯器提示waings:"缺少所需的 lang 特性"…