엔티티를 집계로 작성


10

나는 최근에 엔티티와 그들의 행동분리 하는 방법에 대해 물었다. 과 과이 기사에 링크 된 주요 답변 : http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

여기에 쓰여진 궁극적 인 개념은 다음과 같습니다. 순수한 합의로서의 목표.

C #을 사용하여 게임 엔터티를 순수한 집계로 만드는 방법에 대해 궁금합니다. 나는 이것이 어떻게 작동하는지에 대한 개념을 파악하지 못했습니다. (아마도 엔티티는 특정 인터페이스 또는 기본 유형을 구현하는 객체의 배열입니까?)

나의 현재 생각은 여전히 ​​각 엔티티 유형에 대한 구체적인 클래스를 가지고 관련 인터페이스 (IMoveable, ICollectable, ISpeakable 등)를 구현하는 것입니다.

해당 엔터티에 대한 구체적인 유형을 갖지 않고 순수하게 집계로 엔터티를 만드는 방법은 무엇입니까?


여전히 관심이 있다면 C #으로 소규모 엔티티 시스템을 보낼 수 있습니다. 그것은 아니다 놀라운 ,하지만 작동합니다.
공산주의 오리

답변:


6

링크 된 기사에서 West가 설명한 "순수 집계"접근 방식은 "엔티티"개체를 완전히 없애줍니다. 메모리에 떠 다니는 구성 요소가 있지만 암시 적 관계에 의해서만 묶여 있습니다.

이를 수행하는 한 가지 방법은 소위 선외 접근입니다. 입니다. 이러한 시스템에서 구성 요소는 구성 요소를 관리하거나 제어하는 ​​시스템에 의해 유지됩니다 (여기서는 "관리"라는 용어를 사용하지만, 보유 할 * Manager 클래스가 많다는 것을 의미하는 것은 아닙니다) 구성 요소 유형). 예를 들어, 물리 시스템은 시뮬레이션 세계에서 각 강체를 나타내는 여러 가지 것들을 유지할 수 있으며 그러한 것들을 PhysicsComponents로 노출시킬 수 있습니다. 구성 요소는 해당 하위 시스템에서 처리하는 실제 개체이거나 필요에 따라 해당 개체의 프록시 일 수 있습니다.

이러한 시스템에서는 반드시 "Entity"클래스가이를 구성하는 컴포넌트에 대한 참조 모음을 보유 할 필요는 없습니다. 대신 "엔티티"의 생성 또는 삭제에 대한 알림이 발생하고 구성 요소를 처리하는 각 하위 시스템은 생성 / 파괴 된 엔터티 (일부 데이터에서로드 됨)에 대한 설명을보고 구성 요소가 필요한지 여부를 결정합니다.

이 접근 방식의 장점 중 하나는 각 구성 요소에 대한 참조 영역이 실제로 우수하다는 것입니다. 불행히도 그것은 이상하고 전반적이며 가장 친숙한 구성 요소 기반 엔터티가 아닙니다. 개체가 다른 하위 시스템에서 여전히 보유하고있는 구성 요소에 대한 약한 참조를 집계 한 경우에도 개체를 나타내는 실제 개체를 갖는 것이 매우 편리한 경우가 있습니다. .

컴포넌트 지향 게임 오브젝트 시스템을 구현하는 몇 가지 좋은 방법이 있습니다. 정말, 정말, 정말 당신이 당신의 시스템에서 원하는 요구 사항의 확고한 생각을 가지고 있으면 도움이 - 당신은 유니티 같은 인기있는 프레임 워크 예제 무엇을 볼 수 있습니다. 엄격한 요구 사항을 설정하지 않으면 시스템을 실제로 구축하지 않고도 끝없이 "디자인"하는 문제가 발생하여 완벽한 구현에 헛되지 않을 수 있습니다. 어떤 이유로 든 나는 컴포넌트 시스템에서 이것을 많이 보았습니다.


3

Unity가하는 방식은 모든 스크립트 (귀하의 경우 게임 객체 유형에 특정한 게임 코드)가 기본 클래스에서 파생되는 것입니다.이 클래스 MonoBehaviour자체는보다 관련성이 높은 클래스에서 파생됩니다 Component. GameObject 클래스를 편집하거나 코드에 액세스 할 수 없습니다.

게임 오브젝트는 그 모든 것을 포함해야합니다 Component. 또한 관련 기능 (예 :)을 호출 할 책임도 있습니다 Update. Unity는 리플렉션을 사용하여 호출 할 함수를 결정 하지만 ( 이 페이지 의 "Overridable Functions"섹션 참조 ) 가상으로 만들고 싶을 것입니다.

따라서 Unity에서 사용하는 메커니즘 중 하나는 현재 게임 오브젝트 (또는 그 자식)의 컴포넌트를 유형별로 가져 오는 것입니다. 일반적인 것들을 감싸는 도우미 속성이 있습니다. 예를 들어 게임 오브젝트에 액세스하려는 경우Transform 게임 오브젝트의 위치 / 회전 / 스케일을 제어하기 위해 구성 요소 일반적으로와 같은 작업을 수행해야 this.GetComponent<Transform>().position하지만이를 도우미 this.transform.position호출 로 래핑합니다 . 또 다른 일반적인 패턴은 현재 게임 오브젝트의 Renderer컴포넌트에 액세스하는 것 입니다. 따라서 현재 게임 오브젝트의 머티리얼을 변경하는 것과 같은 작업을 원한다면 다른 스크립트 this.renderer.material = someOtherMaterial에서와 같은 작업을 수행하면 게임 오브젝트가 적절히 업데이트됩니다.

Unity에서 작동하는 방법 중 하나는 에디터를 설정하여 컴포넌트를 이미 연결 한 씬에서 게임 오브젝트를 만들 수 있도록하는 것입니다. 유니티의 경우 모든 게임 객체는이 Transform구성 요소뿐만 아니라 내장 된 같은 종류의 포함 할 수 있습니다 AudioListener또는 Renderer당신이 무엇을 기대하지. 또는 원하는대로 수행하는 고유 한 구성 요소를 추가 할 수 있습니다. 편집기는 구성 요소에 공개 / 직렬화 가능 필드를 표시하므로 동일한 기본 코드를 사용하고 몇 가지 마법 숫자를 변경하려는 경우 다른 스크립트를 만들 필요가 없습니다.

대체로 매우 매끄 럽습니다. 무료 버전의 Unity를 다운로드하고 스크립팅 시스템이 달성하고자하는 개념에 대한 적절한 증거로 설정되는 방식으로 놀아 보는 것이 좋습니다.


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