Collider and Body Components
概述
在Quantum 2中碰撞及物理行為各自有它們自己的元件。
- 新增一個物理碰撞器2D/物理碰撞器3D到一個實體,將實體轉換成一個動態障礙物或觸發,其可透過它的轉換被移動。
- 新增一個物理主體2D/物理主體3D,允許實體被物理求解所控制。
要求
轉換2D/轉換3D、物理碰撞器2D/物理碰撞器3D及物理主體2D/物理主體3D元件緊密交織在一起。其中一些是其它功能運作所需。完整的相依性清單如下:
要求 | 轉換 | 物理碰撞器 | 物理主體 | |
---|---|---|---|---|
元件 | ||||
轉換 | ✓ | ✗ | ✗ | |
物理碰撞器 | ✓ | ✓ | ✗ | |
物理主體 | ✓ | ✓ | ✓ |
這些相依性組建在另一者之上,因此如果您希望啟用一個物理主體,您需要以下列順序新增元件到一個實體:
- 轉換
- 物理碰撞器
- 物理主體
物理主體元件
新增 物理主體 ECS元件到一個實體,將使物理引擎能夠考慮這個實體。請注意: 使用一個 物理主體 需要實體已經有一個 轉換 及一個 物理碰撞器。
您可以透過手動地在程式碼中,或是透過Unity中的實體原型元件,來建立及初始化元件。
C#
var entity = f.Create();
var transform = new Transform2D();
var collider = PhysicsCollider2D.Create(f, Shape2D.CreateCircle(1));
var body = PhysicsBody2D.CreateDynamic(1);
f.Set(entity, transform);
f.Set(entity, collider);
f.Set(entity, body);
同樣的規則適用於3D物理:
C#
var entity = f.Create();
var transform = Transform3D.Create();
var shape = Shape3D.CreateSphere(FP._1);
var collider = PhysicsCollider3D.Create(shape);
var body = PhysicsBody3D.CreateDynamic(FP._1);
f.Set(entity, transform);
f.Set(entity, collider);
f.Set(entity, body);
在實體原型方法的情形,元件將以它們已儲存的值被初始化。
針對動態實體,物理碰撞器3D支援只支援以下形狀3D:
- 球狀
- 盒狀
質量中心
質量中心,以下簡稱 CoM,可在物理主體元件上被設定。CoM代表一個相對於轉換元件中指定的位置的位移。更改CoM的位置允許影響適用於物理主體的力的適用方式。
預設下,CoM設定為物理碰撞器形狀的質量中心。這是由物理主體設定下拉式選單中的Reset Center of Mass On Added
來執行。
請注意:為了自訂CoM位置,您 必須 取消勾選Reset Center of Mass On Added
旗標;不然當物理主體元件被新增到實體時,CoM將被重設為碰撞器的質量中心。
上述設定常用於一個表現為均勻密度主體的實體,也就是具有均勻密度的主體。然而,CoM及碰撞器位移被分別設定。下表說明各個組合。
物理碰撞器位移 | 物理主體CoM | 在已新增的旗標上重設質量中心 | 結果位置 |
---|---|---|---|
預設位置 = 0, 0, 0 自訂值 = 任何不同於預設位置的位置 |
|||
預設位置 | 預設位置 | 開/關 | 碰撞器質量中心及CoM位置是相等於 轉換位置。 |
自訂值 | 預設位置 | 開 | 碰撞器質量中心是來自轉換的位移,並且CoM是相等於碰撞器質量中心位置。 |
自訂值 | 預設位置 | 關 | 碰撞器質量中心是來自轉換位置的位移。 CoM是相等於轉換位置。 |
自訂值 | 自訂位置 | 開 | 碰撞器質量中心是來自轉換位置的位移。 CoM是相等於碰撞器質量中心位置。 |
自訂值 | 自訂位置 | 關 | 碰撞器質量中心是來自轉換位置的位移。 CoM是來自轉換位置的位移。 |
複合碰撞器CoM
複合形狀的CoM是基於其所有形狀的元素的面積(2D)或體積(3D)的質量中心的加權平均值的組合。
關鍵點
總結而言,關於CoM設定,以下是您需要記得的主要重點。
- 物理碰撞器位移及物理主體CoM位置是有別於彼此。
- 預設下,物理主體設定有旗標
Reset Center of Mass On Added
及Reset Inertia on Added
。 - 為了設定一個自訂CoM,在物理主體設定中取消勾選
Reset Center of Mass On Added
旗標。 - 如果
Reset Center of Mass On Added
旗標在物理主體設定上已勾選,CoM將在其被新增到實體時被自動設定為物理碰撞器質量中心——無論編輯器中指定的CoM位置為何。
應用外部力
物理主體API允許手動應用外部力到一個主體。
C#
// This is the 3D API, the 2D one is identical.
public void AddTorque(FPVector3 amount)
public void AddAngularImpulse(FPVector3 amount)
public void AddForce(FPVector3 amount, FPVector3? relativePoint = null)
public void AddLinearImpulse(FPVector3 amount, FPVector3? relativePoint = null)
// relativePoint is a vector from the body's center of mass to the point where the force is being applied, both in world space.
// If a relativePoint is provided, the resulting Torque is computed and applied.
public void AddForceAtPosition(FPVector3 force, FPVector3 position, Transform3D* transform)
public void AddImpulseAtPosition(FPVector3 force, FPVector3 position, Transform3D* transform)
// Applies the force/impulse at the position specified while taking into account the CoM.
正如您可以從API所收集,物理主體的角動量及線性動量可能會受到以下應用的影響:
- 力;或
- 脈衝。
雖然它們很相似,有一個關鍵的不同; 力 應用於一段時間,而 脈衝 是立即性的。您可以思考成:
- 力 = 每個差量時間的力
- 脈衝 = 每個幀的力
請注意: 在Quantum中差量時間是固定的,並且取決於Simulation Config
資產中設定的模擬率。
一個 脈衝 將產生相同的效果,無論模擬率為何。然而,一個 力 取決於模擬率——這意味著在一個30的模擬率下應用一個1的力向量到一個主體,如果您增加模擬率到60,則差量時間將為一半,並且因此已整合的力也將減半。
一般而言,當希望發生一個準時的及立即的更改時,建議使用一個 脈衝;而一個 力 則應該用於持續性、漸進性,或應用於較長時間的情形。
初始化元件
為了初始化一個 物理主體 為一個動態或運動主體,您可以使用它們相應的建立函數。這些方法可透過PhysicsBody2D
及PhysicsBody3D
層級存取,例如:
- PhysicsBody3D.CreateDynamic
- PhysicsBody3D.CreateKinematic
形狀設定
為了透過由資料驅動的設計來初始化物理碰撞器及物理主體,您可以使用 形狀設定 類型(形狀2D設定,及形狀3D設定)。這些架構可被新增為一個屬性,到任何Quantum資料資產,可從Unity編輯(針對形狀、大小等等)。
C#
// data asset containing a shape config property
partial class CharacterSpec {
// this will be edited from Unity
public Shape2DConfig Shape2D;
public Shape3DConfig Shape3D;
public FP Mass;
}
當初始化主體時,我們使用形狀設定,而非直接使用形狀:
C#
// instantiating a player entity from the Frame object
var playerPrototype = f.FindAsset<EntityPrototype>(PLAYER_PROTOTYPE_PATH);
var playerEntity = playerPrototype.Container.CreateEntity(f);
var playerSpec = f.FindAsset<CharacterSpec>("PlayerSpec");
var transform = Transform2D.Create();
var collider = PhysicsCollider2D.Create(playerSpec.Shape2D.CreateShape(f));
var body = PhysicsBody2D.CreateKinematic(playerSpec.Mass);
// or the 3D equivalent:
var transform = Transform3D.Create();
var collider = PhysicsCollider3D.Create(playerSpec.Shape3D.CreateShape())
var body = PhysicsBody3D.CreateKinematic(playerSpec.Mass);
// Set the component data
f.Set(playerEntity, transform);
f.Set(playerEntity, collider);
f.Set(playerEntity, body);
啟用物理回調
一個實體可以有一個與它關聯的物理回調的集。這些可以透過程式碼,或在 實體原型 的 物理碰撞器 元件中被啟用。
如需取得如何以程式碼設定物理回調及 執行 它們相應的 信號 的資訊,請參照物理操作手冊中的 回調 條目。
運動學
在Quantum v2中,有4個不同的方式讓一個物理實體有運動學上的行為:
透過 只 有一個
PhysicsCollider
元件。在這種情況下,實體沒有一個 物理主體 元件;換句話說,沒有質量、拖曳、力/扭力整合等等...。您可以自由操控實體轉換,然而,當碰撞動態主體時,碰撞脈衝被解決的方式,就是實體如同靜止一樣(線性速度及角速度為0)。透過 停用
PhysicsBody
元件。如果您在一個 物理主體 上設定IsEnabled
屬性為 偽,則物理引擎將以與第1點所示相同的方式處理實體——也就是只有一個碰撞器元件。沒有力或速度被整合。如果您希望主體的行為在您稍後重新啟用它之前 暫時地 類似於一個靜止實體及其設定(質量、拖曳力係數等等),這是合適的。透過在一個
PhysicsBody
元件 上 設定IsKinematic
屬性為 真。在這種情況下,物理引擎將不會移動影響 物理主體 本身,但當處理碰撞時,主體的線性速度及角速度將仍然影響 其他主體。如果您希望控制實體移動而非讓物理引擎控制,並且知道您負責手動移動一個實體並且控制一個主體的速度,同時仍然讓其他動態主體回應它,請使用這個方法。透過以
CreateKinematic
來 初始化PhysicsBody
。如果在主體的完整生命週期中期待主體行為是運動學的,您可以簡單地建立它為一個運動學的主體。這將從一開始就讓 物理主體 行為類似於3之中的行為。如果主體最終需要成為動態主體,您可以簡單地透過CreateDynamic
方法建立一個新的主體,並且設定IsKinematic = true
。設定 是運動學 為真/偽,並且可以在任何時間無縫地重新初始化 物理主體 元件為動態/運動學。
物理碰撞器元件
停用/啟用元件
從Quantum 2.1開始,PhysicsCollider
元件配備有一個Enabled
屬性。當設定這個屬性為false
,在PhysicsSystem
中,有著PhysicsCollider
的實體將被忽略。
因為PhysicsBody
需要一個 啟用的 PhysicsCollider
,它也將有效地被停用。
在運行階段改變形狀
可以在初始化 物理碰撞器 之後改變其形狀。
C#
var collider = f.Get<PhysicsCollider3D>(entity);
collider.Shape = myNewShape;
f.Set(entity, collider);
當一個 物理主體 第一次被新增,它基於物理碰撞器的形狀來計算慣性及CoM。因此建議在改變碰撞器的形狀後調用ResetInertia
及ResetCenterOfMass
。
C#
// following the snippet above
var body = f.Get<PhysicsBody3D>(entity);
body.ResetCenterOfMass(f, entity); // Needs to be called first
body.ResetInertia(f, entity); // Needs to be called second
f.Set(entity, body);
如果針對舊的和/或新的形狀,任何下列事項為真,則ResetCenterOfMass
特別需要被調用:
- 形狀有一個位置位移
- 形狀是一個複合形狀
- 質量中心有一個位移