엔터티 구성 요소 시스템-객체의 변형을 구현하는 방법?


11

엔진 용 엔터티 구성 요소 시스템을 설계 할 때 특정 유형의 구성 요소를 저장하고 검색하는 방식에 약간의 걸림돌이 생겼습니다.

먼저이 질문에 사용할 용어를 약간 정리해 보겠습니다.

  • 특정 시스템과 관련된 데이터를 저장하는 데이터 구조를 " 구성 요소 "라고합니다.
  • " 시스템 "은 구성 요소를 사용하여 사용자와의 게임 상태 / 인터페이스를 업데이트하는 메서드 및 데이터 구조의 집계입니다.
  • " 엔티티 "는 기본적으로 특정 구성 요소를 검색하고 게임 로직에서 데이터를 수정하는 데 사용되는 ID입니다.

각 시스템은 구성 요소 유형 (예 : 물리-> 물리적 구성 요소, AI-> AI 구성 요소, 렌더링-> 렌더링 구성 요소)의 (ID 맵핑) 배열을 소유하므로 데이터를 효율적으로 반복 할 수 있습니다.

그러나 모든 구성 요소가 시스템에서 특별히 소유하는 것은 아닙니다. 예를 들어, 변형 구성 요소는 객체의 위치, 회전 및 배율을 저장합니다. 그것은 물리학, AI, 렌더링 등과 같은 많은 시스템에서 사용되기 때문에 엔티티의 가장 중요한 부분 중 하나입니다 (Unity는 필수 요소입니다).

이것은 내가 직면하고있는 거의 문제입니다. Transform은 다른 많은 시스템에서 사용되기 때문에 각 구성 요소에 사용할 하나를 검색하려면 어떻게해야합니까? 내가 볼 수있는 한 가지 해결책은 각 구성 요소 저장소를 자체 엔티티 ID로 만드는 것입니다. 이와 같은 구성 요소를 쉽게 검색 할 수는 있지만 그렇게 효율적이지는 않으며 다른 격리 된 독립 데이터 번들로서 구성 요소의 개념에 위배됩니다.

이 문제를 해결하는 적절한 방법이 있습니까? 변환도 컴포넌트 여야합니까?


3
+1 "먼저,이 질문에 사용할 약간의 용어를 정리하겠습니다 :"
Vaillancourt

이 사이트에서 이러한 유형의 질문을 더보고 싶습니다. +1
S. Tarık Çetin

모든 구성 요소를 전역 변수로 저장하십시오
Miles Rout

답변:


2

이것은 매우 광범위한 질문이며, 그 대답은 아키텍처에 따라 크게 다릅니다. 그러나 일반적인 답변을 드리려고합니다.

물리 및 렌더링 시스템은 확실히 변환이 필요하지만 AI 시스템은 그렇지 않습니다. 따라서 변환을 자체 컴포넌트 클래스로 캡슐화하는 것이 좋습니다. 이러한 모든 관심있는 시스템은 동일한 데이터를 사용하므로 엔티티가 변환 오브젝트에 대한 포인터 또는 다른 곳에 저장된 변환 오브젝트의 ID를 갖는 것이 적합합니다.

후자의 솔루션을 선택하면 변환에 관심이있는 각 시스템은 변환 오브젝트가 저장된 모든 위치에 액세스해야합니다.

전자를 선택하면 각 시스템이 엔티티 자체에 액세스하고 변환을 요청하기 만하면됩니다.

전자의 경우, 문제는 OOP 규칙을 위반하지 않으면 서 각 시스템에 대한 변환을 위해 스토리지에 대한 액세스 권한을 부여하는 방법이됩니다.

후자의 경우에는 그러한 문제가 없지만 구성 요소 객체의 ID가 아닌 객체에 대한 포인터를 저장하도록 엔티티 객체 디자인을 변경해야합니다.

개인적으로 선호하는 것은 많은 디자인 문제를 단순화하기 때문에 구성 요소 객체에 대한 포인터를 저장하도록 엔티티 클래스를 디자인하는 것입니다. 이런 식으로 변환이 필요한 각 시스템은 엔터티에 요청하고 그렇지 않은 경우 무시할 수 있습니다. 그러나 이것은 포인터 고유의 계산 오버 헤드를 가지므로 캐시 누락 비용이 발생합니다.

이에 대한 자세한 내용 은이 ECS 개요 를 참조하십시오.

하루가 끝나면 개발의 용이성 또는 성능 중 어느 것이 더 중요한지 결정하는 것은 귀하의 몫입니다.

마지막으로, 귀하의 질문은 ECS 지지자들이 생각하는 디자인 질문의 훌륭한 예이며, 명확한 은탄환 솔루션은 없습니다.


제안 해 주셔서 감사합니다. 하지만 AI 시스템에 물체의 위치가 필요하지 않은 이유는 무엇입니까?
CRefice

위치 (3 개의 부동 소수점 벡터)와 평행 이동 (위치 벡터로 구성된 변형 행렬)을 혼동하고 있습니다. 변환 매트릭스는 변환, 회전 및 스케일 변환으로 구성됩니다. AI 시스템에서 필요로하는 것보다 훨씬 많은 정보이지만 확실히 위치 벡터를 추출 할 수는 있습니다. 개인적으로는 위치, 방향 및 크기를 자체 구성 요소로 분리하고 변환을 만들고 업데이트하는 데 사용합니다.
이안 영

@IanYoung 분리하면 위치 나 방향을 따로하는 것보다 위치와 방향을 더 자주 필요로하는 경우, 선을 분리하는 것이 좋은 것보다 더 해를 끼칠 수 있습니다. 이 경우 위치 및 방향 데이터 속성을 단일 구성 요소에 배치하면 캐시 성능이 향상 될 수 있습니다.
Naros

1
선호하는 것은 세 가지, 위치, 방향 및 스케일을 단일 구성 요소로 결합하는 것이며 특정 하위 시스템에 위치 또는 방향이 필요한 경우 데이터 복제 및 게임 루프에서 명확하게 정의 된 지점에서 동기화하는 것을 옹호합니다 .
Naros

@Naros 예, 이것이 의미하는 바는 두 가지 구성 요소, 변환 및 (내 프레임 워크에서) SpatialData는 위치, 속도, 방향 및 각속도를 포함합니다. 위치와 방향은 변환을 구성하고 업데이트하는 데 사용됩니다.
이안 영
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.