컴포넌트 기반 게임에서 충돌을 올바르게 처리하는 방법은 무엇입니까?


11

구성 요소를 중심으로 설계된 게임에서 충돌을 올바르게 처리하는 방법으로 머리를 감싸려고합니다.

많은 예제 PhysicsComponent에 엔티티의 구성 요소 목록에 추가되는 종류가 있지만 실제 구현은 혼란 스럽습니다.

이것이 작동 PhysicsComponent하려면 주변 세계에 액세스해야합니다. 이것은 나에게 직관적이지 않습니다. 컴포넌트가 컨테이너 (엔터티)뿐만 아니라 컨테이너의 컨테이너 (세계)를 인식하지 않아야합니까?

나에게 레벨이나 장면은 이러한 엔티티와 모든 게임 업데이트의 목록을 유지해야하고, 충돌을 결정하기 위해 엔티티를 반복합니다.

내 질문은 첫째, 이것이 좋은 디자인인지 아닌지, 둘째는 충돌 할 수있는 엔티티를 결정하는 방법입니다. 솔리드 엔티티가 빈 IRigidBody 인터페이스를 구현하여 레벨에서 충돌을 지원하는 엔티티를 결정할 수 있다고 가정합니다. 그러나 이것이 구성 요소 설계를 깨뜨리고 있습니까?

대신 빈 RigidBody 구성 요소를 포함해야합니까? 항상 비어있는 것은 아니기 때문에이 방법이 더 나을 수 있으며이 방법은 미래에 대비할 수 있습니다. 이것의 유일한 문제는 복잡성입니다. 장면은 모든 엔티티뿐만 아니라 모든 엔티티의 컴포넌트를 반복하여이 RigidBody 컴포넌트가 있는지 판별해야합니다.

셋째, 그들이 충돌 할 때 두 엔티티 모두 어떻게 든 정보를 받아야하며 이것을 달성하는 방법이 확실하지 않습니다.

두 엔티티가 모두 HealthComponent를 포함하고 있고 두 오브젝트가 충돌하면 임의의 값으로 감소 될 것이라고 가정 해 봅시다.

그러나 장면이 너무 많은 책임이 있습니까? 나는 실체가 접근해서는 안되는 많은 것들에 대해 장면이 책임질 때 이것이 손에서 벗어나 다루기 어려워지는 것을 볼 수 있었다.

편집 : 자세한 내용으로 질문이 업데이트되었습니다.


4
이 답변은 다음의 링크에 적합합니다 : gamedev.stackexchange.com/questions/13797/…
Andrew Russell

Andrew의 링크 된 답변, James의 답변 및 Nick Wiggill의 답변은 모두 +1입니다. 구성 요소는 데이터와 메서드가 모두있는 일반적인 클래스보다 데이터라고 생각하면됩니다 (메소드가 없지만 많은 책임을지지 않아야 함). 좋은 구성 요소 프레임 워크의 예 는 Artemis 구성 요소 시스템 ( piemaster.net/2011/07/entity-component-artemis )을 참조하십시오.
michael.bartnett

답변:


5

솔직히 구성 요소 디자인 측면에서 내 구성 요소는 필요하지 않은 한 서로에 대해 알지 못합니다 (매우 드 rare니다). 그럼에도 불구하고 나는 일반적으로 구성 요소가 구성 요소 대신 직접 해당 구성 요소의 일부 관리 시스템과 통신하는 것을 선호합니다. (스크립팅 인터페이스는 객체 대 객체처럼 보이지만 실제 엔진에는 해당되지 않습니다).

이를 위해 먼저 말한 내용과 충돌하여 객체를 테스트해야 할 때마다 존재하는 물리 컴포넌트와 함께하겠습니다. 이제 분명히 이러한 객체는 충돌 해결시 다른 구성 요소에 자신을 알려야 할 수도 있지만 언급 한 것처럼 이벤트는 다른 인터페이스 (관리자 또는 이벤트 메시징 시스템 인 경우)를 통해 객체로 나가는 것을 선호합니다. 예를 들어 그중 하나가 있습니다).

나는 당신이 올바른 길을 가고 있다고 생각합니다. 그리고 더 많은 '예, 그 소리가납니다'그래서 .. 네, 맞습니다.

도움이 되었기를 바랍니다!


3

일반적으로 게임 엔진은 타사 라이브러리를 사용하여 엔티티 간의 충돌을 감지합니다. 이 시나리오에서는 PhysicsComponent가있는 엔티티를 "물리"세계에 작성하거나 등록합니다. 그리고 두 엔티티 (A와 B) 사이의 충돌을 감지 할 때마다 일반적으로 엔티티 B와 충돌하고 엔티티 B와 동일하다는 것을 알리는 엔티티 A에 대한 콜백을 호출하여 엔티티 A와 충돌했음을 알립니다.

2D의 경우 잘 알려진 무료 물리 라이브러리는 Box2D입니다. 또한 Chipmunk를 살펴볼 가치가 있습니다. 3D의 경우 Bullet은 무료입니다 (아마도 찾을 수있는 최고의 무료). Havok과 PhysX는 많은 트리플 A 게임에서 사용되는 것으로 유명합니다.


2

당신이 겪고있는 문제는 충돌 감지 (다른 물리 참조를 위해 하나의 물리 구성 요소 베어링 엔티티가 필요한 유일한 이유)가 일반적으로 게임 루프 또는 직접적으로 더 높은 수준에서 수행되는 것을 보는 것입니다 이를 수행하는 도우미 함수 / 클래스 몇 주 전에 누군가에게대답 은 비슷한 근거에서 개체 제거에 대해 이야기하고 충돌로 인해 개체 중 하나가 파괴되면 주어진 맥락에서 동일한 대답이 당신과 매우 관련이 있음을 명심하십시오. "더 높은 힘"은 여전히 ​​몸의 정리를 관리해야하기 때문에 ...

엔터티간에 만이 작업을 수행하는 것은 일반적으로 실행 가능하지 않습니다. 충돌 감지와 같은 직접 관리 또는 예를 들어 이벤트 디스패치 등을 통해 견고한 아키텍처에는 거의 항상 그러한 것들에 대한 프록시가 있습니다. 클라이언트 쪽 메시징 관리자가 플레이어로부터 발송 된 메시지를 수신하여 서버로 전송하여 모든 사람에게 다시 브로드 캐스트하는 플레이어 메시징 시스템.


2

나는 프로젝트에서 당신과 정확히 같은 문제에 직면하고 있습니다. 내가 다루기로 결정한 방법은 물리 엔진에서 몸을 유지하는 "ColliderComponent"를 갖는 것입니다. 바디는 외부에서 정의되어 (런타임에로드되는 쉐이프 정의) 물리 세계 그들이 속한 게임 엔터티에 추가됩니다.

충돌로 알림을받을 "충돌 청취자"를 부착 할 수있는 Box2D를 사용하고 있습니다. 바디 사용자 데이터에 "ColliderComponent"에 대한 포인터를 추가하므로 충돌의 일부인 두 개의 ColliderComponent를 얻을 수 있습니다.

따라서 충돌이 발생할 때 발생하는 일은 다음과 같습니다. 충돌의 일부인 ColliderComponents는 소유자 오브젝트 (게임 엔터티)에 메시지를 보내어 해당 메시지를 모든 구성 요소에 브로드 캐스트합니다.

그런 다음 모든 구성 요소가 해당 메시지에 반응 할 수 있으므로 "health-component"는 상태 등에서 5 점을 제거 할 수 있습니다.


+1 : 나는 매우 비슷한 접근법을 사용하고 있습니다. 충돌 한 엔티티 유형에 따라 발생할 피해량을 어떻게 결정합니까?
Den

@ 발생한 충돌에 따라 다른 메시지 (또는 메시지 데이터)를 보냅니다. 처리 할 다른 사례가 많지 않기 때문에 이것은 잘 작동합니다.
bummzack

0

충돌 "세계"를 알고있는 충돌 시스템을 만듭니다. 그런 다음 충돌 구성 요소에서 충돌 시스템에 점 A에서 B로 광선을 투사하고 충돌 여부에 따라 반응하도록 지시합니다.

행운을 빕니다. 충돌 시스템이 게임 엔진에서 가장 지루한 부분 중 하나라는 것을 알았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.