This document is about: QUANTUM 2
SWITCH TO

Collider and Body Components

概述

在Quantum 2中碰撞及物理行為各自有它們自己的元件。

  • 新增一個物理碰撞器2D/物理碰撞器3D到一個實體,將實體轉換成一個動態障礙物或觸發,其可透過它的轉換被移動。
  • 新增一個物理主體2D/物理主體3D,允許實體被物理求解所控制。

要求

轉換2D/轉換3D、物理碰撞器2D/物理碰撞器3D及物理主體2D/物理主體3D元件緊密交織在一起。其中一些是其它功能運作所需。完整的相依性清單如下:

要求 轉換 物理碰撞器 物理主體
元件
轉換
物理碰撞器
物理主體

這些相依性組建在另一者之上,因此如果您希望啟用一個物理主體,您需要以下列順序新增元件到一個實體:

  1. 轉換
  2. 物理碰撞器
  3. 物理主體

物理主體元件

新增 物理主體 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);

在實體原型方法的情形,元件將以它們已儲存的值被初始化。

adjusting an entity prototype's physics properties via the unity editor
透過Unity編輯器來調整一個實體原型的物理屬性。

針對動態實體,物理碰撞器3D支援只支援以下形狀3D:

  • 球狀
  • 盒狀

質量中心

質量中心,以下簡稱 CoM,可在物理主體元件上被設定。CoM代表一個相對於轉換元件中指定的位置的位移。更改CoM的位置允許影響適用於物理主體的力的適用方式。

animated examples of how various com affect the same physicsbody
動畫示例,展示各種CoM如何影響同樣的物理主體。

預設下,CoM設定為物理碰撞器形狀的質量中心。這是由物理主體設定下拉式選單中的Reset Center of Mass On Added來執行。

請注意:為了自訂CoM位置,您 必須 取消勾選Reset Center of Mass On Added旗標;不然當物理主體元件被新增到實體時,CoM將被重設為碰撞器的質量中心。

defaults flags in the physicsbody config
在Unity編輯器中檢視的物理主體設定中的預設旗標。

上述設定常用於一個表現為均勻密度主體的實體,也就是具有均勻密度的主體。然而,CoM及碰撞器位移被分別設定。下表說明各個組合。

物理碰撞器位移 物理主體CoM 在已新增的旗標上重設質量中心 結果位置
預設位置 = 0, 0, 0
自訂值 = 任何不同於預設位置的位置
預設位置 預設位置 開/關 碰撞器質量中心及CoM位置是相等於 轉換位置。
自訂值 預設位置 碰撞器質量中心是來自轉換的位移,並且CoM是相等於碰撞器質量中心位置。
自訂值 預設位置 碰撞器質量中心是來自轉換位置的位移
CoM是相等於轉換位置。
自訂值 自訂位置 碰撞器質量中心是來自轉換位置的位移
CoM是相等於碰撞器質量中心位置。
自訂值 自訂位置 碰撞器質量中心是來自轉換位置的位移
CoM是來自轉換位置的位移

複合碰撞器CoM

複合形狀的CoM是基於其所有形狀的元素的面積(2D)或體積(3D)的質量中心的加權平均值的組合。

關鍵點

總結而言,關於CoM設定,以下是您需要記得的主要重點。

  1. 物理碰撞器位移及物理主體CoM位置是有別於彼此。
  2. 預設下,物理主體設定有旗標Reset Center of Mass On AddedReset Inertia on Added
  3. 為了設定一個自訂CoM,在物理主體設定中取消勾選Reset Center of Mass On Added旗標。
  4. 如果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,則差量時間將為一半,並且因此已整合的力也將減半。

一般而言,當希望發生一個準時的及立即的更改時,建議使用一個 脈衝;而一個 則應該用於持續性、漸進性,或應用於較長時間的情形。

初始化元件

為了初始化一個 物理主體 為一個動態或運動主體,您可以使用它們相應的建立函數。這些方法可透過PhysicsBody2DPhysicsBody3D層級存取,例如:

  • 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);

啟用物理回調

一個實體可以有一個與它關聯的物理回調的集。這些可以透過程式碼,或在 實體原型物理碰撞器 元件中被啟用。

setting physics callbacks via the entity prototype's physics properties in the unity editor
透過Unity編輯器中的實體原型的物理屬性來設定物理回調。

如需取得如何以程式碼設定物理回調及 執行 它們相應的 信號 的資訊,請參照物理操作手冊中的 回調 條目。

運動學

在Quantum v2中,有4個不同的方式讓一個物理實體有運動學上的行為:

  1. 透過 有一個PhysicsCollider 元件。在這種情況下,實體沒有一個 物理主體 元件;換句話說,沒有質量、拖曳、力/扭力整合等等...。您可以自由操控實體轉換,然而,當碰撞動態主體時,碰撞脈衝被解決的方式,就是實體如同靜止一樣(線性速度及角速度為0)。

  2. 透過 停用 PhysicsBody 元件。如果您在一個 物理主體 上設定IsEnabled屬性為 ,則物理引擎將以與第1點所示相同的方式處理實體——也就是只有一個碰撞器元件。沒有力或速度被整合。如果您希望主體的行為在您稍後重新啟用它之前 暫時地 類似於一個靜止實體及其設定(質量、拖曳力係數等等),這是合適的。

  3. 透過在一個PhysicsBody 元件設定 IsKinematic屬性為 。在這種情況下,物理引擎將不會移動影響 物理主體 本身,但當處理碰撞時,主體的線性速度及角速度將仍然影響 其他主體。如果您希望控制實體移動而非讓物理引擎控制,並且知道您負責手動移動一個實體並且控制一個主體的速度,同時仍然讓其他動態主體回應它,請使用這個方法。

  4. 透過以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。因此建議在改變碰撞器的形狀後調用ResetInertiaResetCenterOfMass

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()` **必須被** 首先調用,然後才是`ResetInertia()`。

如果針對舊的和/或新的形狀,任何下列事項為真,則ResetCenterOfMass特別需要被調用:

  • 形狀有一個位置位移
  • 形狀是一個複合形狀
  • 質量中心有一個位移
Back to top