강건한 OO 디자인에서 Entity-Component-System (ECS) 디자인에 이르기까지 약간의 경험을 통해 이야기하겠습니다.
얼마 전 나는 너와 똑 같았고, 비슷한 속성을 가진 여러 가지 유형의 것들이 있었고 다양한 객체를 만들고 상속을 사용하여 해결하려고했습니다. 매우 똑똑한 사람 은 그렇게하지 말고 대신 Entity-Component-System을 사용하십시오.
이제 ECS 는 큰 개념이며 제대로 이해하기가 어렵습니다. 엔터티, 구성 요소 및 시스템을 올바르게 구축하는 데 필요한 많은 작업이 있습니다. 그러기 전에 용어를 정의해야합니다.
- 엔티티 : 이것은이다 것은 , 플레이어, 동물, NPC, 무엇이든 . 컴포넌트가 필요합니다.
- 구성 요소 : 이는 귀하의 경우 "이름"또는 "나이"또는 "부모"와 같은 속성 또는 특성 입니다.
- 시스템 : 이것은 구성 요소의 논리 또는 동작 입니다. 일반적으로 구성 요소 당 하나의 시스템을 구축하지만 항상 가능한 것은 아닙니다. 또한 때때로 시스템이 다른 시스템 에 영향을 주어야 합니다.
그래서 여기에 내가 갈 곳이 있습니다.
무엇보다도 ID
캐릭터를 위한를 만드 십시오. int
, Guid
당신이 원하는대로. 이것이 "엔터티"입니다.
둘째, 당신이 겪고있는 다양한 행동에 대해 생각하기 시작하십시오. "패밀리 트리"와 같은 것들 — 행동입니다. 엔티티의 속성으로 모델링하는 대신 모든 정보 를 보유하는 시스템을 빌드 하십시오 . 그런 다음 시스템은 무엇을할지 결정할 수 있습니다.
마찬가지로, "캐릭터가 살아 있거나 죽었습니까?"에 대한 시스템을 구축하려고합니다. 이것은 다른 모든 시스템에 영향을 미치기 때문에 설계에서 가장 중요한 시스템 중 하나입니다. 일부 시스템은 "죽음"문자 (예 : "스프라이트"시스템)를 삭제하고 다른 시스템은 내부적으로 새로운 상태를 더 잘 지원하기 위해 항목을 다시 정렬 할 수 있습니다.
예를 들어 "스프라이트", "도면"또는 "렌더링"시스템을 구축합니다. 이 시스템은 캐릭터에 표시 할 스프라이트와 표시 방법을 결정해야합니다. 그런 다음 캐릭터가 죽으면 제거하십시오.
또한 캐릭터에게 무엇을해야하는지, 어디로 가야하는지 등을 알려주는 "AI"시스템. 다른 많은 시스템과 상호 작용하고이를 기반으로 결정을 내려야합니다. 다시 말하지만 죽은 문자는 더 이상 아무것도하지 않기 때문에이 시스템에서 제거 될 수 있습니다.
"이름"시스템 및 "패밀리 트리"시스템은 아마도 문자 (생존 또는 사망)를 메모리에 보관해야합니다. 이 시스템은 캐릭터의 상태에 관계없이 해당 정보를 리콜해야합니다. (Jim은 매장 한 후에도 여전히 Jim입니다.)
또한 시스템 이보다 효율적으로 반응 할 때 변경 하는 이점도 있습니다. 시스템에는 자체 타이머가 있습니다. 일부 시스템은 빠르게 발사해야하지만 일부는 그렇지 않습니다. 여기서 우리는 게임을 효율적으로 운영하기 시작합니다. 우리는 밀리 초마다 날씨를 다시 계산할 필요가 없습니다. 아마도 5 년마다 그렇게 할 수 있습니다.
또한보다 창의적인 활용도를 제공합니다. A에서 B까지의 경로 계산을 처리하고 필요에 따라 업데이트 할 수있는 "Pathfinder"시스템을 구축하여 이동 시스템이 "어디에서해야합니까? 다음에가? " 우리는 이제 이러한 우려를 완전히 분리하고보다 효과적으로 추론 할 수 있습니다. 운동은 경로를 찾을 필요가 없습니다.
시스템의 일부를 외부에 노출하려고합니다. 당신의 Pathfinder
시스템에서 아마 당신은 원할 것입니다 Vector2 NextPosition(int entity)
. 이러한 방식으로 이러한 요소를 엄격하게 제어되는 배열 또는 목록에 유지할 수 있습니다. 더 작은 struct
유형을 사용 하면 구성 요소를 더 작고 연속적인 메모리 블록에 유지하여 시스템 업데이트를 훨씬 빠르게 수행 할 수 있습니다 . (특히 시스템에 대한 외부 영향이 최소화 된 경우 이제는 시스템과 같은 내부 상태 만 신경 쓰면됩니다 Name
.)
그러나, 나는 이것을 충분히 강조 할 수 없습니다. 이제는 타일, 객체 등을 포함하여 Entity
단지입니다 ID
. 엔티티가 시스템에 속하지 않으면 시스템은 그것을 추적하지 않습니다. 우리는, 우리의 "트리"객체를 생성에 저장할 수있는이 수단 Sprite
과 Movement
(나무가 이동하지 않습니다,하지만 그들은 "위치"구성 요소가) 시스템과 다른 시스템의 그들을 유지. 나무를 렌더링하는 것은 종이 인형 외에 캐릭터와 다르지 않기 때문에 더 이상 나무에 대한 특별한 목록이 필요하지 않습니다. 합니다 (어떤 Sprite
시스템을 제어 할 수 있습니다, 또는 Paperdoll
시스템을 제어 할 수 있습니다.) 이제 우리는 NextPosition
약간의 재 작성 할 수 있습니다 Vector2? NextPosition(int entity)
, 그리고 그것은 반환 할 수 null
그것에 대해 상관하지 않는다 엔티티 위치를. 우리는 또한 이것을 나무에 적용하고 나무와 바위를 NameSystem.GetName(int entity)
반환 null
합니다.
나는 가까운이를 그릴 수 있습니다, 그러나 여기에서 아이디어는 당신에게 ECS에 대한 몇 가지 배경을 제공하는 것입니다, 당신은 할 수있는 방법 정말 당신에게 게임에 대한 더 나은 디자인을 제공하기 위해 활용. 성능을 높이고 관련없는 요소를 분리하며보다 체계적인 방식으로 유지할 수 있습니다. (당신이있는 경우에 내가보기 엔 F 번호 체크 아웃하는 것이 좋습니다 F # 및 LINQ 등이 또한 쌍 아니라 기능적인 언어 / 설정, 아니 이미 그것은 쌍 아주 잘 C #을 사용하면 함께 사용할 때.)