콜라이더 및 바디 컴포넌트
소개
충돌과 물리 작용은 Quantum 2에서 각각 고유한 컴포넌트를 가집니다.
- PhysicsCollider2D/PhysicsCollider3D를 엔티티에 추가하면 엔티티가 변환을 통해 이동할 수 있는 동적 장애물 또는 트리거로 바뀝니다.
- PhysicsBody2D/PhysicsBody3D를 추가하면 엔티티가 Physics Solver에 의해 제어될 수 있습니다.
최소 사양
Transform2D/Transform3D, PhysicsCollider2D/PhysicsCollider3D 및 PhysicsBody2D/PhysicsBody3D 컴포넌트는 긴밀하게 얽혀 있습니다. 따라서 이들 중 일부는 다른 것이 기능하기 위한 요구 사항입니다. 전체 종속성 목록은 아래에서 확인할 수 있습니다.
필요사항 | 트랜스폼 | PhysicsCollider | PhysicsBody | |
---|---|---|---|---|
컴포넌트 | ||||
트랜스폼 | ✓ | ✗ | ✗ | |
PhysicsCollider | ✓ | ✓ | ✗ | |
PhysicsBody | ✓ | ✓ | ✓ |
이러한 종속성은 서로에 기반하므로 PhysicsBody를 활성화하려면 다음 순서로 컴포넌트를 엔티티에 추가해야 합니다:
- Transform
- PhysicsCollider
- 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 메소드의 경우 저장된 값으로 컴포넌트가 초기화됩니다.
PhysicsCollider3D는 동적 엔티티에 대해 다음 Shape3D만 지원합니다:
- Sphere
- Box
질량 중심
질량 중심, 여기서부터는 단순히 CoM 으로 언급되며, PhysicsBody 컴포넌트에 설정할 수 있습니다. CoM은 트랜스폼 컴포넌트에 지정된 위치에 상대적인 오프셋을 나타냅니다. CoM의 위치를 변경하면 물리적인 바디에 힘이 가해지는 방식에 영향을 미칠 수 있습니다.
기본적으로 CoM은 PhysicsCollider의 셰이프의 중심에 설정됩니다. 이는 PhysicsBody Config 드로어의 Reset Center of Mass On Added
에 의해 수행됩니다.
주의: CoM 위치를 사용자 정의하려면 반드시 Reset Center of Mass On Added
플래그의 선택을 하지 않아야 합니다. 그렇지 않으면 PhysicsBody 컴포넌트가 엔티티에 추가될 때 CoM이 콜라이더의 중심으로 재설정됩니다.
위의 구성은 균일한 밀도의 물체, 즉 균일한 밀도의 물체처럼 행동하는 엔티티에 일반적으로 사용됩니다. 그러나 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 구성과 관련하여 빼야 할 주요 사항은 다음과 같습니다.
- PhysicsCollider 오프셋과 PhysicsBody CoM 위치는 서로 다릅니다.
- 기본적으로 PhysicsBody Config에는
Reset Center of Mass On Added
및Reset Inertia on Added
플래그가 있습니다. - 사용자 정의 CoM을 설정하려면 PhysicsBody Config에서
Reset Center of Mass On Added
플래그의 선택을 체크하지 않아야 합니다. - 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 를 동적 또는 키네마틱 바디로 초기화하려면 해당 생성 함수를 사용할 수 있습니다. 이러한 메서드는 PhysicsBody2D
및 PhysicsBody3D
클래스를 통해 접근할 수 있습니다.
- 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 Prototype의 PhysicsCollider 컴포넌트를 통해 활성화할 수 있습니다.
물리 콜백을 코드로 설정하고 해당 신호를 구현 하는 방법에 대한 자세한 내용은 물리 매뉴얼의 콜백 항목을 참조하십시오.
Kinematic
Quantum v2에서 물리 실체가 운동학적 행동을 하는 방법은 4가지가 있습니다.
PhysicsCollider
컴포넌트 만 있으면 됩니다. 이 경우 엔티티는 PhysicsBody 컴포넌트를 가지고 있지 않습니다. 즉, 질량, 드래그, 힘/토크 통합 등이 없습니다. 하지만 엔티티 변환을 마음대로 조작할 수 있습니다. 하지만 동적 물체와 충돌할 때 충돌 임펄스는 엔티티가 정지해 있는 것처럼 해결됩니다(선형 및 각속도 0).PhysicsBody
컴포넌트를 비활성화합니다. PhysicsBody_ 의IsEnabled
속성을 false 로 설정하면 물리 엔진은 점 1에 표시된 것과 동일한 방식으로 엔티티를 처리합니다. 즉, 충돌기 컴포넌트만 있는 것으로 간주합니다. 어떤 힘이나 속도도 통합되지 않습니다. 이 방법은 본문이 임시로 고정된 엔티티처럼 동작하도록 하고 나중에 바디를 다시 활성화할 때 해당 구성(질량, 드래그 계수 등)을 원하는 경우에 적합합니다.PhysicsBody
component 의IsKinematic
속성을 _true_로 설정합니다. 이 경우 물리 엔진이 움직이는 것은 Physics Body 자체에 영향을 미치지 않지만, 충돌을 해결할 때 물체의 선형 및 각속도는 여전히 다른 물체 에 영향을 미칩니다. 물리 엔진에 맡기는 대신 엔티티 이동을 제어하고 다른 동적 물체가 반응하는 동안 수동으로 엔티티를 이동하고 물체의 속도를 제어할 책임이 있다는 것을 알고 싶을 때 사용합니다.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을 계산합니다. 따라서 콜라이더 모양을 변경 후 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
는 이전 및/또는 새 모양에 대해 다음 중 하나라도 해당되는 경우 호출해야 합니다.
- 셰이프에 위치 오프셋이 있습니다.
- 셰이프는 복함 셰이프입니다.
- 질량 중심에는 오프셋이 있습니다.