강건한 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 #을 사용하면 함께 사용할 때.)