엔터티 구성 요소 시스템을 구성하는 방법에 대한 모든 사람들이 자신의 생각을 가지고 있기 때문에 대답하기 어려운 질문입니다. 내가 할 수있는 최선은 내가 찾은 것들 중 가장 유용한 것들을 당신과 나누는 것입니다.
실재
ECS에 대한 뚱뚱한 접근 방식을 취했을 것입니다. 아마도 프로그래밍의 극단적 인 방법이 매우 비효율적이라고 생각하기 때문입니다 (인간 생산성 측면에서). 이를 위해 엔터티는 더 특수화 된 클래스에 상속되는 추상 클래스입니다. 엔터티에는 많은 가상 속성과이 엔터티가 존재하는지 여부를 알려주는 간단한 플래그가 있습니다. 렌더 시스템에 대한 질문 Entity
과 관련 하여 다음과 같습니다.
public abstract class Entity {
public bool IsAlive = true;
public virtual SpatialComponent Spatial { get; set; }
public virtual ImageComponent Image { get; set; }
public virtual AnimationComponent Animation { get; set; }
public virtual InputComponent Input { get; set; }
}
구성 요소
구성 요소는 아무 것도 모르 거나 알지 못한다 는 점에서 "멍청한" 것입니다. 그들은 다른 구성 요소에 대한 참조가 없으며 일반적으로 함수가 없습니다 (C #에서 작동하므로 속성을 사용하여 getter / setter를 처리합니다. 함수가있는 경우 보유하고있는 데이터 검색을 기반으로합니다).
시스템
시스템은 덜 멍청하지만 여전히 멍청한 자동 장치입니다. 전체 시스템에 대한 컨텍스트가없고 다른 시스템에 대한 참조가 없으며 개별 처리에 필요한 몇 개의 버퍼를 제외하고 데이터를 보유하지 않습니다. 시스템에 따라 특화된 방법 Update
또는 Draw
방법이 있거나 경우에 따라 둘 다있을 수 있습니다.
인터페이스
인터페이스는 내 시스템의 핵심 구조입니다. 그들은 무엇 System
을 처리 할 수 있고 무엇을 할 수 있는지 정의하는 데 사용됩니다 Entity
. 렌더링과 관련된 인터페이스는 다음 IRenderable
과 같습니다 IAnimatable
.
인터페이스는 시스템에 사용 가능한 구성 요소를 알려줍니다. 예를 들어, 렌더링 시스템은 엔티티의 경계 상자와 그릴 이미지를 알아야합니다. 내 경우에는 SpatialComponent
and ImageComponent
입니다. 따라서 다음과 같이 보입니다.
public interface IRenderable {
SpatialComponent Component { get; }
ImageComponent Image { get; }
}
렌더링 시스템
렌더링 시스템은 어떻게 엔티티를 그리나요? 실제로는 매우 간단하므로 아이디어를 제공하기 위해 제거 된 클래스를 보여 드리겠습니다.
public class RenderSystem {
private SpriteBatch batch;
public RenderSystem(SpriteBatch batch) {
this.batch = batch;
}
public void Draw(List<IRenderable> list) {
foreach(IRenderable obj in list) {
this.batch.draw(
obj.Image.Texture,
obj.Spatial.Position,
obj.Image.Source,
Color.White);
}
}
}
수업을 보면 렌더 시스템은 무엇인지조차 모릅니다 Entity
. 그것이 아는 전부는 IRenderable
그리고 단순히 그 (것)들을 그릴 그들의 명부가 주어진다.
그것이 어떻게 작동 하는가
새 게임 오브젝트를 작성하는 방법과 시스템에 피드를 공급하는 방법을 이해하는 데 도움이 될 수도 있습니다.
엔터티 만들기
모든 게임 오브젝트는 Entity 및 해당 게임 오브젝트가 수행 할 수있는 작업을 설명하는 적용 가능한 인터페이스에서 상속됩니다. 화면에 애니메이션으로 표시되는 모든 내용은 다음과 같습니다.
public class MyAnimatedWidget : Entity, IRenderable, IAnimatable {}
시스템 공급
게임 세계에 존재하는 모든 엔티티의 목록을이라는 단일 목록으로 유지 List<Entity> gameObjects
합니다. 그런 다음 각 프레임을 통해 해당 목록을 살펴보고 인터페이스 유형 (예 : List<IRenderable> renderableObjects
및)을 기반으로 더 많은 목록에 객체 참조를 복사합니다 List<IAnimatable> animatableObjects
. 이런 식으로 다른 시스템이 동일한 엔티티를 처리해야하는 경우 가능합니다. 그런 다음 해당 목록을 각 시스템 Update
또는 Draw
방법에 전달하고 시스템에서 작업을 수행하도록합니다.
생기
애니메이션 시스템이 어떻게 작동하는지 궁금 할 것입니다. 필자의 경우 IAnimatable 인터페이스를보고 싶을 수도 있습니다.
public interface IAnimatable {
public AnimationComponent Animation { get; }
public ImageComponent Image { get; set; }
}
여기서 주목해야 할 것은 인터페이스 의 ImageComponent
측면이 IAnimatable
읽기 전용이 아니라는 것입니다. 그것은이 세터 .
짐작할 수 있듯이 애니메이션 구성 요소는 애니메이션에 대한 데이터 만 보유합니다. 프레임 목록 (이미지 구성 요소), 현재 프레임, 그릴 초당 프레임 수, 마지막 프레임 증분 이후의 경과 시간 및 기타 옵션.
애니메이션 시스템은 렌더링 시스템과 이미지 구성 요소 관계를 이용합니다. 단순히 애니메이션의 프레임이 증가함에 따라 엔터티의 이미지 구성 요소를 변경하기 만합니다. 이렇게하면 애니메이션이 렌더링 시스템에 의해 간접적으로 렌더링됩니다.