엔터티 구성 요소 시스템에서 엔터티 '유형'식별


10

엔터티에 명시적인 '유형'(예 : 플레이어)이없고 단순히 구성 요소 모음 인 경우 시스템에서 작업하지 않아야하는 엔터티를 어떻게 식별합니까? 예를 들어, Pong 게임에서 패들과 공은 모두 창 경계와 충돌합니다. 그러나 각각의 충돌 처리 시스템은 다르므로 시스템이 잘못된 유형의 엔티티를 처리해서는 안됩니다.

void PlayerCollisionSystem::update(std::vector<Entity *> entities) {
  typedef std::vector<Entity *>::iterator EIter;
  for (EIter i = entities.begin(); i != entities.end(); ++i) {
    Entity *player = *i; // How do I verify that the entity is a player?

    // Get relevant components.
    PositionComponent *position = player->getComponent<PositionComponent>();
    VelocityComponent *velocity = player->getComponent<VelocityComponent>();
    SpriteComponent *sprite = player->getComponent<SpriteComponent>();

    // Detect and handle player collisions using the components.
  }
}

플레이어와 볼 모두 충돌 처리에 대해 동일한 관련 구성 요소 유형을 공유하지만 시스템 구현은 다릅니다.

모든 게임 엔터티의 컨테이너가 있는 경우 Entity와 같은 멤버 변수 를 상속 하거나 포함 하지 않고 특정 유형의 엔터티식별하려면 어떻게해야std::string type 합니까?

답변:


21

Nicol Bolas의 대답은 똑같지 만, 한 발짝 물러서서 멀리서 문제를 살펴보십시오. 실체의 유형이 실제로 필요하지 않습니다.

"객체에 구성 요소가 있는지"여부 만주의해야하며 X문제는 올바르게 식별되지 않은 것 X입니다. 두 개체가 다르게 동작하는 경우 다른 구성 요소를 제공하거나 다른 개체 구성에 대해 다르게 동작하도록 구성 요소에 부울 플래그를 추가하십시오. 구성 요소 시스템을 사용하여 엔티티 "유형"이 아닌 동작에 대한 결정을 내립니다. 이것이 컴포넌트를 사용하는 요점입니다.

PaddlePhysics구성 요소 / 시스템과 BallPhysics다르게 작동하는 경우 별도의 구성 요소 / 시스템 을 가질 수 있습니다 . 또는 BounceBall에만있는 StopAtBoundary구성 요소 BallPaddle동작의 일부가 복잡하여 코드 공유를 정당화 할 수있는 구성 요소를 갖도록 구성 요소를보다 세분화 된 조각으로 나눌 수 있습니다. 아니면 그냥 할 수 PongPhysics부울 플래그가 구성 요소 Bounces세트 true에 대한 Ballfalse를 들어 Paddle. 기본 WallCollision구성 요소를 만든 다음 해당 구성 요소를 파생 BallWallCollision하여 필요한 추가 동작을 추가 할 수 있습니다.


4
"vanilla"ECS에는 아무런 제약이나 문제가 없기 때문에 이것이 정답이라고 생각합니다. 마커 역할을하는 전용 구성 요소를 만들어 태그 지정 엔터티를 쉽게 수행 할 수 있습니다. 또한 유용한 기능은 없지만 태그 역할 만하는 더미 PlayerTypeComponent 일 수도 있습니다.
tiguchi

19

시스템은 유용한 경우에만 유용 합니다. 엔터티가 "단순한 구성 요소 모음"인 시스템이 엔터티가 대부분 "구성 요소 모음"인 시스템보다 유용 하지 않은 경우 에는 그렇게하십시오 .

"순수한"시스템을 만드는 것을 멈추고 필요한 것을하는 좋은 시스템을 만드는 데 집중하십시오 . 구성 요소가 더 이상 유용하지 않을 때까지 구성 요소를 사용하십시오. 그런 다음 다른 것을 사용하십시오.

당신은 이미 이것에 대해 생각하는 것보다 더 많은 시간을 보냈습니다.


very nice +1 "당신은 이미 이것에 대해 생각하는 것보다 더 많은 시간을 보냈습니다"
wes

8
나는 이것이 전혀 답이라고 생각하지 않는다. ECS를 다듬는 주제는 큰 관심을 기울여야 할 주제이며, Garee (2013 년에 이것을 게시했을 때)는 아마도 그것에 대해 생각하는 데 충분한 시간을 소비하지 않았을 것입니다. 주제가 더 많은 시간을 가질 자격이 없다는 개념은 시스템이 단순하거나 사소하고 일반적으로 우리의 시간을 감당할 수 없다는 것을 의미합니다. Sean Middleditch의 대답은 실제로 질문을 닫는 대신 질문하려고 시도하기 때문에 대답을 선호합니다.
개빈 윌리엄스

좋은 대답입니다. 나는 때때로 나 자신에게 이것을 말해야한다. 앞으로 나아가는 데 집중하십시오.
Dominic Bou-Samra 2016 년

5

엔티티에 명시 적 유형을 제공하려는 경우 가장 쉬운 방법은 엔티티 클래스에서 유형 변수를 정의하는 것입니다. EC 패턴이 유용 할 경우에만 유지하십시오.

그렇지 않으면 유형이 구성 요소 속성을 통해 암시됩니다. 예를 들어, 물리 구성 요소는 모바일 대 고정에 대한 속성을 갖습니다. 그런 다음 시스템은 두 개의 모바일이 충돌하는시기를 확인합니다 (볼 및 패들). 마찬가지로 충돌 시스템이 어떻게 반응해야하는지에 대한 속성을 가질 수 있습니다. 그냥 물건을 멈추거나 그것을 반영? 속성을 살펴보면 엔터티가 무엇인지에 대한 아이디어를 얻을 수 있지만 관련이 없어야합니다. 시스템은 작업중인 엔티티 유형이 무엇인지 알 필요가 없으며 제공된 구성 요소를 사용하여 충분한 정보를 제공해야합니다.

마지막으로 유형을 포함하는 추가 구성 요소를 추가 할 수 있지만 엔터티에 유형을 추가 할 때 EC 시스템의 목적을 무너 뜨리는 많은 유형별 코드를 작성하게됩니다.


0

엔터티는 구성 요소 집합입니다. 깔끔한 레이블을 임의 세트에 할당 할 수 없습니다. 유형 제약 조건을 포기하는 것이 큰 유연성을위한 가격입니다.

물론 구성 요소에 제한을주는 특수한 유형의 엔터티 클래스를 가질 수 있습니다.

이상적으로 구성 요소는 독립적입니다. 따라서 문제의 해결책은 각 하위 구성 요소에서 충돌 처리를 순서대로 호출하는 것입니다. 실제 응용 프로그램에는 상호 종속성 및 주문 문제가 있습니다. 이 경우 Entity 클래스의 모든 메소드에 '디스패처'로직이 필요합니다.

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