[DOTS] System

황교선·2023년 8월 9일
0

DOTS

목록 보기
4/5

Systems 유튜브 링크

System

  • C# struct
  • 세 메소드가 있음
    • OnCreate
      • 첫 업데이트 이전에 한 번만 호출됨
    • OnDestory
      • 시스템이 월드에서 제거되거나 월드 자체가 Disposed될 때 호출됨
    • OnUpdate
      • 대게 프레임 당 한 번 실행됨
    • 세 메소드 다 SystemState ref 매개변수를 가짐
      • System’s World에 접근을 가능케해줌
      • EntityManager에 접근을 가능케해줌
    • OnCreate → OnUpdate (Loop) → OnDestory
  • 각 시스템은 월드에 종속됨
  • 보통 월드의 시스템에서만 월드의 엔티티에 접근함
    • Systems, Monobehaviours 등을 포함한 어떤 코드도 아무 월드에 접근이 가능
[BurstCompile]
public partial struct MySystem : ISystem
{
  [BurstCompile]
  public void OnCreate(ref SystemState state)
  {
  }

  [BurstCompile]
  public void OnDestory(ref SystemState state)
  {
  }

  [BurstCompile]
  public void OnUpdate(ref SystemState state)
  {
  }
}

System Group

  • 파일 시스템처럼, 시스템 그룹은 원하는만큼의 자식 시스템과 자식 시스템 그룹을 가질 수 있음
  • OnUpdate
    • 각 Group의 OnUpdate 메소드는 오버라이드를 통해 커스텀화할 수 있음
    • 기본 OnUpdate는 sudo random sorted order를 통해 각 자식 시스템을 실행시킴
    • 그룹에 자식이 추가되고 삭제될 때마다 자식 리스트는 재정렬됨
    • 실행시키는 순서는 UpdateBefore, UpdateAfter 어트리뷰트를 추가함으로서 제어할 수 있음
      [UpdateBefore(typeof(FooSystem))]
      [UpdateAfter(typeof(BarSystem))]
      public class MySystem : ISystem
      {
      }
public class MySystemGroup : ComponentSystemGroup
{
  protected override void OnUpdate()
  {
    base.OnUpdate(); // update every child in sorted order
  }
}

위의 System Editor Window는 정렬된 업데이트 순서의 Hierachy 를 보여줍니다. 3개의 기본 시스템 그룹은 위 사진에서 주황 박스로 테두리 친 그룹입니다. 이 세 그룹은 유니티 메인 루프 자체에서 업데이트됩니다. Initalization 시스템 그룹은 셋업 작업에 사용되고, Simulation 시스템 그룹은 코어 게임 로직에 사용되며, Presentation 시스템 그룹은 렌더링에 사용됩니다.

그룹의 OnUpdate를 오버라이드하면, 원하는 자식만 실행시키거나, 한 프레임에 여러 번 실행시킬 수 있습니다. Fixed Step Simulation 시스템 그룹을 예로들면 MonoBehaviour의 FixedUpdate와 같이 고정된 프레임 레이트로 업데이트합니다.

Automatic bootstrapping

  • 세 탑-레벨 시스템 그룹으로 default world를 생성함
    • Initalization, Simulation, Presentation
  • 각 시스템과 시스템 그룹이 생성될 때 그 인스턴스를 default world에 추가함
    • default SimulationSystemGroup에 추가하기 싫다면 시스템 클래스에 어트리뷰트를 추가하면 됨
    • [UpdateInGroup(typeof(MyGroup))]
  • Automatic bootstrapping을 끄고 싶다면 #UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP 전처리를 붙일 것

SystemState

  • GetEntityQuery()

  • GetComponentTypeHandles<T.>()

  • System 안에서는 EntityManager가 아닌 SystemState를 통해 쿼리와 컴포넌트를 다룰 것

    • 컴포넌트 타입을 시스템을 통해서 Register 하기 때문

    • 예를들면 SystemState의 GetEntityQuery를 통해 Foo, Bar를 소유하고 있는 Entity를 Query할 때, Foo, Bar 컴포넌트를 시스템을 통해 Register 함

    • EntityManager를 통해 위와 동일한 것을 실행할 경우 Register되지 않음

    • 접근하는 시스템에서 Register를 하는 것이 중요한 이유는 depedency 프로퍼티 때문

      • 시스템 업데이트 전에 실행되는 것이 두 가지가 있음
        1. SystemState의 dependency 프로퍼티가 저장될 때 Complete 메소드를 호출(?)
        2. 동일한 컴포넌트를 접근하는 모든 다른 시스템의 dependency에게서 권한을 할당받아야함
    • System에서 필요한 Job Dependency를 명확히하는 것에 목적이 있음

      • 모든 Job은 직간접적으로 Dependency가 업데이트 되어야함

      • 시스템 업데이트가 반환되기 전에, Dependency가 할당될 수 있어야함

        위의 사진으로 예를들면, 업데이트 메소드에서는 Dependency 프로퍼티를 할당받은 핸들에 의존하는 두 개의 잡을 스케줄합니다. 그리고 업데이트가 반환되기 전에 이 두 핸들을 하나로 결합하고 이를 Dependency 프로퍼티에 할당됩니다.

        이 코드에서는 dependency에 마지막의 handle만 포함되었지만 두 코드가 동일하게 작동합니다. 작동하는 이유는 첫 번째 잡 핸들이 두 번째 잡 핸들에 포함되었기에, 두 번째 잡 핸들만을 디펜던시에 포함시켜도 첫번째 잡 핸들이 간접적으로 포함되었기 때문입니다.

profile
성장과 성공, 그 사이 어딘가

0개의 댓글