This document is about: QUANTUM 2
SWITCH TO

콜라이더 및 바디 컴포넌트

소개

충돌과 물리 작용은 Quantum 2에서 각각 고유한 컴포넌트를 가집니다.

  • PhysicsCollider2D/PhysicsCollider3D를 엔티티에 추가하면 엔티티가 변환을 통해 이동할 수 있는 동적 장애물 또는 트리거로 바뀝니다.
  • PhysicsBody2D/PhysicsBody3D를 추가하면 엔티티가 Physics Solver에 의해 제어될 수 있습니다.

최소 사양

Transform2D/Transform3D, PhysicsCollider2D/PhysicsCollider3D 및 PhysicsBody2D/PhysicsBody3D 컴포넌트는 긴밀하게 얽혀 있습니다. 따라서 이들 중 일부는 다른 것이 기능하기 위한 요구 사항입니다. 전체 종속성 목록은 아래에서 확인할 수 있습니다.

필요사항 트랜스폼 PhysicsCollider PhysicsBody
컴포넌트
트랜스폼
PhysicsCollider
PhysicsBody

이러한 종속성은 서로에 기반하므로 PhysicsBody를 활성화하려면 다음 순서로 컴포넌트를 엔티티에 추가해야 합니다:

  1. Transform
  2. PhysicsCollider
  3. PhysicsBody

PhysicsBody 컴포넌트

엔티티에 PhysicsBody ECS 컴포넌트를 추가하면 이 엔티티를 물리 엔진에서 고려할 수 있습니다. 주의: PhysicsBody 를 사용하려면 Transform 과 가 PhysicsCollider 이미 있어야 합니다.

코드에서 수동으로 컴포넌트를 생성 및 초기화할 수도 있고 유니티의 EntityPrototype 컴포넌트를 통해 초기화할 수도 있습니다.

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 Physics에도 적용됩니다:

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

EntityPrototype 메소드의 경우 저장된 값으로 컴포넌트가 초기화됩니다.

adjusting an entity prototype's physics properties via the unity editor
유니티 편집기를 통해 엔티티 프로토타입의 물리적 속성을 조정합니다.

PhysicsCollider3D는 동적 엔티티에 대해 다음 Shape3D만 지원합니다:

  • Sphere
  • Box

질량 중심

질량 중심, 여기서부터는 단순히 CoM 으로 언급되며, PhysicsBody 컴포넌트에 설정할 수 있습니다. CoM은 트랜스폼 컴포넌트에 지정된 위치에 상대적인 오프셋을 나타냅니다. CoM의 위치를 변경하면 물리적인 바디에 힘이 가해지는 방식에 영향을 미칠 수 있습니다.

animated examples of how various com affect the same physicsbody
다양한 CoM이 동일한 Physical Body에 어떻게 영향을 미치는지 보여주는 애니메이션 예제

기본적으로 CoM은 PhysicsCollider의 셰이프의 중심에 설정됩니다. 이는 PhysicsBody Config 드로어의 Reset Center of Mass On Added에 의해 수행됩니다.

주의: CoM 위치를 사용자 정의하려면 반드시 Reset Center of Mass On Added 플래그의 선택을 하지 않아야 합니다. 그렇지 않으면 PhysicsBody 컴포넌트가 엔티티에 추가될 때 CoM이 콜라이더의 중심으로 재설정됩니다.

defaults flags in the physicsbody config
유니티 편집기에 표시된 PhysicsBody Config의 기본 플래그

위의 구성은 균일한 밀도의 물체, 즉 균일한 밀도의 물체처럼 행동하는 엔티티에 일반적으로 사용됩니다. 그러나 CoM 및 콜라이더 오프셋은 별도로 구성됩니다. 이러한 조합은 아래 표에 설명되어 있습니다.

PhysicsCollider 오프셋 PhysicsBody CoM 추가된 플래그에 질량 중심 재설정 결과 포지션
기본 위치 = 0, 0, 0
사용자 지정 값 = any position differing from the default position
기본 위치 기본 위치 On / Off Collider Centroid 및 CoM 포지션은 트랜스폼 위치와 동일.
사용자 지정 값 기본 위치 On Collider Centroid는 트랜스폼의 오프셋이며 CoM은 Collider Centroid 포지션과 동일.
사용자 지정 값 기본 위치 Off Collider Centroid는 트랜스폼 위치의 오프셋.
CoM은 트랜스폼 위치와 동일.
사용자 지정 값 사용자 지정 위치 On Collider Centroid은 트랜스폼 위치의 오프셋.
CoM은 Collider Centroid 위치와 동일.
사용자 지정 값 사용자 지정 위치 Off Collider Centroid는 트랜스폼 위치의 오프셋.
CoM은 트랜스폼 위치의 오프셋

복합 콜라이더 CoM

복합 셰이프의 CoM은 영역(2D) 또는 볼륨(3D)의 가중 평균에 기초한 모든 셰이프의 요소 중심체의 조합입니다.

주요 사항

요약하면, CoM 구성과 관련하여 빼야 할 주요 사항은 다음과 같습니다.

  1. PhysicsCollider 오프셋과 PhysicsBody CoM 위치는 서로 다릅니다.
  2. 기본적으로 PhysicsBody Config에는 Reset Center of Mass On AddedReset Inertia on Added 플래그가 있습니다.
  3. 사용자 정의 CoM을 설정하려면 PhysicsBody Config에서 Reset Center of Mass On Added 플래그의 선택을 체크하지 않아야 합니다.
  4. PhysicsBody Config에서 Reset Center of Mass On Added 플래그가 선택되어 있으면 에디터에 지정된 CoM 위치에 관계없이 엔티티에 추가될 때 CoM이 자동으로 PhysicsCollider 중심부로 설정됩니다.

외부 힘 적용하기

PhysicsBody 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에서 수집할 수 있듯이, PhysicsBody의 각도 및 선형 모멘텀은 다음을 적용하여 영향을 받을 수 있습니다.

  • 힘; 또는
  • 충돌.

유사하지만, 핵심이 다릅니다. force 는 일정 기간에 걸쳐 적용되지만 impulse 는 즉시 적용됩니다. 다음과 같이 생각할 수 있습니다.

  • Force = 델타 타임별 힘
  • Impulse = 프레임별 힘

노트: Quantum 델타 타임은 Simulation Config 에셋에 설정된 시뮬레이션 속도에 따라 고정됩니다.

impulse 는 시뮬레이션 속도에 관계없이 동일한 효과를 생성합니다. 그러나 force 는 시뮬레이션 속도에 따라 달라집니다. 즉, 시뮬레이션 속도를 30으로 높이면 델타 타임이 60으로 증가하여 힘도 절반으로 감소합니다.

일반적으로 시간적절하고 즉각적인 변경을 의도하는 경우에는 impulse 를 사용하는 것이 바람직하며, force 는 지속적으로, 점진적으로 또는 더 오랜 기간에 걸쳐 적용되는 어떤 것에 사용되어야 합니다.

컴포넌트 초기화

PhysicsBody 를 동적 또는 키네마틱 바디로 초기화하려면 해당 생성 함수를 사용할 수 있습니다. 이러한 메서드는 PhysicsBody2DPhysicsBody3D클래스를 통해 접근할 수 있습니다.

  • PhysicsBody3D.CreateDynamic
  • PhysicsBody3D.CreateKinematic

ShapeConfigs

데이터 기반 설계를 통해 PhysicsCollider 및 PhysicsBody를 초기화하려면 ShapeConfig 유형(Shape2DConfig, 및 Shape3DConfig)을 사용할 수 있습니다. 이러한 구조체는 유니티(모양, 크기 등)에서 편집할 수 있는 모든 Quantum 데이터 에셋에 속성으로 추가할 수 있습니다.

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

물리 콜백 사용

엔티티와 연결된 일련의 물리적 콜백을 가질 수 있습니다. 코드 또는 Entity PrototypePhysicsCollider 컴포넌트를 통해 활성화할 수 있습니다.

setting physics callbacks via the entity prototype's physics properties in the unity editor
유니티 편집기에서 엔티티 프로토타입의 물리 속성을 통해 물리 콜백을 설정합니다.

물리 콜백을 코드로 설정하고 해당 신호구현 하는 방법에 대한 자세한 내용은 물리 매뉴얼의 콜백 항목을 참조하십시오.

Kinematic

Quantum v2에서 물리 실체가 운동학적 행동을 하는 방법은 4가지가 있습니다.

  1. PhysicsCollider 컴포넌트 있으면 됩니다. 이 경우 엔티티는 PhysicsBody 컴포넌트를 가지고 있지 않습니다. 즉, 질량, 드래그, 힘/토크 통합 등이 없습니다. 하지만 엔티티 변환을 마음대로 조작할 수 있습니다. 하지만 동적 물체와 충돌할 때 충돌 임펄스는 엔티티가 정지해 있는 것처럼 해결됩니다(선형 및 각속도 0).

  2. PhysicsBody 컴포넌트를 비활성화합니다. PhysicsBody_ 의 IsEnabled 속성을 false 로 설정하면 물리 엔진은 점 1에 표시된 것과 동일한 방식으로 엔티티를 처리합니다. 즉, 충돌기 컴포넌트만 있는 것으로 간주합니다. 어떤 힘이나 속도도 통합되지 않습니다. 이 방법은 본문이 임시로 고정된 엔티티처럼 동작하도록 하고 나중에 바디를 다시 활성화할 때 해당 구성(질량, 드래그 계수 등)을 원하는 경우에 적합합니다.

  3. PhysicsBody componentIsKinematic 속성을 _true_로 설정합니다. 이 경우 물리 엔진이 움직이는 것은 Physics Body 자체에 영향을 미치지 않지만, 충돌을 해결할 때 물체의 선형 및 각속도는 여전히 다른 물체 에 영향을 미칩니다. 물리 엔진에 맡기는 대신 엔티티 이동을 제어하고 다른 동적 물체가 반응하는 동안 수동으로 엔티티를 이동하고 물체의 속도를 제어할 책임이 있다는 것을 알고 싶을 때 사용합니다.

  4. CreateKinematic을 사용하여 PhysicsBody를 초기화합니다. 바디가 전체 수명 동안 운동학적 역할을 할 것으로 예상되면 간단히 운동학적 바디로 만들 수 있습니다. 이렇게 하면 Physics Body 는 처음부터 3과 같이 동작합니다. 바디가 최종적으로 동적 본체가 되어야 하는 경우, CreateDynamic메서드를 사용하여 새 바디를 만들고 IsKinematic = true 를 설정합니다. IsKinematic 을 true/false로 설정하고 언제든지 PhysiscBody 컴포넌트를 다이내믹/키네마틱으로 다시 초기화할 수 있습니다.

PhysicsCollider 컴포넌트

컴포넌트 사용/미사용

Quantum 2.1 이후 PhysicsCollider 컴포넌트는 Enabled 속성을 갖추고 있습니다. 이 속성을 false로 설정하면 PhysicsCollider를 가진 엔티티가 PhysicsSystem에서 무시됩니다.

PhysicsBody에는 active PhysicsCollider가 필요하기 때문에 이 역시 사실상 비활성화됩니다.

런타임에 모양 변경하기

초기화된 후 PhysicsCollider 의 모양을 변경할 수 있습니다.

C#

var collider = f.Get<PhysicsCollider3D>(entity);
collider.Shape = myNewShape;
f.Set(entity, collider);

PhysicsBody 를 처음 추가할 때 이 값은 PhysicsCollider의 모양을 기준으로 관성 및 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