본문 바로가기

Unity/DOTS

DOTS 학습을 위한 기초 정리 #13 System Update Order

반응형

System Update Order

구성 요소 시스템 그룹을 사용하여 시스템의 업데이트 순서를 지정합니다. 시스템의 클래스 선언에서 [UpdateInGroup]특성을 사용하여 그룹에 시스템을 배치할 수 잇습니다. 그런 다음 [UpdateBefor] 및 [UpdateAfter] 특성을 사용하여 그룹 내에 업데이트 순서를 지정할 수 있습니다.

 

ECS 프레임워크는 프레임의 올바른 단계에서 시스템을 업데이트하는 데 사용할 수 있는 기본 시스템 그룹을 생성합니다. 그룹 내의 모든 시스템이 올바른 단계에서 업데이트되고 그룹 내의 순서에 따라 업데이트되도록 한 그룹을 다른 그룹에 내포할 수 있습니다.

Component System Groups

ComponentSystemGroup 클래스는 특정 순서로 함께 업데이트해야 하는 관련 구성 요소 시스템의 목록을 나타냅니다. ComponentSystemGroup은 ComponentSystemBase에서 파생되었으므로 모든 중요한 방법으로 구성 요소 시스템 처럼 작동합니다. 즉, 다른 시스템과 비교하여 명령할 수 있으며 OnUpdate() 메서드를 사용할 수 있습니다. 가장 관련성이 있는 것은 구성 요소 시스템 그룹이 다른 구성 요소 시스템 그룹에 중첩되어 계층 구조를 형성할 수 있음을 의미합니다.

System Ordering Attributes

기존 시스템 주문 속성은 약간 다른 의미와 제한으로 유지됩니다.

  • [UpdateInGroup] — 이 시스템이 구성원이어야 하는 ComponentSystemGroup을 지정합니다. 이 특성이 생략되면 시스템이 자동으로 기본 World의 SimulationSystemGroup에 추가됩니다. (아래 참조)
  • [UpdateBefore] and [UpdateAfter] — 다른 시스템과 관련된 시스템을 주문합니다. 이러한 특성에 대해 지정된 시스템 유형은 동일한 그룹의 구성원이어야 합니다. 그룹 경계를 넘나드는 주문은 두 시스템이 모두 포함된 가장 깊은 그룹에서 처리됩니다.
    • Example: System A와 Group A에 System B가 Group A와 Group B에 있고, Group A와 B가 모두 Group C의 멤버인 경우 Group A와 B의 순서에 따라 System A와 B의 상대적 순서가 결정되므로 시스템을 명시적으로 정렬할 필요가 없습니다.
  • [DisableAutoCreation] —기본 월드 초기화 중에 시스템이 생성되지 않도록합니다. 시스템을 명시적으로 생성하고 업데이트 해야합니다. 그러나 이 태그가 있는 시스템을 ComponentSystemGroup의 업데이트 목록에 추가할 수 있으며, 이 업데이트 목록은 해당 목록의 다른 시스템과 마찬가지로 자동으로 업데이트됩니다. 

 

Default System Groups

기본 월드에는 ComponentSystemGroup 인스턴스의 계층이 포함되어 있습니다. Unity Player 루프에는 3개의 루트 수준 시스템 그룹만 추가됩니다. (다음 목록에는 각 그룹의 미리 정의된 멤버 시스템도 나와 있음)

  • InitializationSystemGroup (플레이어의 루프의 초기화 단계 끝에 업데이트 됨)
    • BeginInitializationEntityCommandBufferSystem
    • CopyInitialTransformFromGameObjectSystem
    • SubSceneLiveLinkSystem
    • SubSceneStreamingSystem
    • EndInitializationEntityCommandBufferSystem
  • SimulationSystemGroup (플레이어 루프의 업데이트 단계 끝에 업데이트 됨)
    • BeginSimulationEntityCommandBufferSystem
    • TransformSystemGroup
      • EndFrameParentSystem
      • CopyTransformFromGameObjectSystem
      • EndFrameTRSToLocalToWorldSystem
      • EndFrameTRSToLocalToParentSystem
      • EndFrameLocalToParentSystem
      • CopyTransformToGameObjectSystem
    • LateSimulationSystemGroup
    • EndSimulationEntityCommandBufferSystem
  • PresentationSystemGroup (플레이어 루프의 PreLAteUpdate[사전 업데이트] 단계가 끝날 때 업데이트 됩니다.)
    • BeginPresentationEntityCommandBufferSystem
    • CreateMissingRenderBoundsFromMeshRenderer
    • RenderingSystemBootstrap
    • RenderBoundsUpdateSystem
    • RenderMeshSystem
    • LODGroupSystemV1
    • LodRequirementsUpdateSystem
    • EndPresentationEntityCommandBufferSystem

이 몰곡의 특정 내용은 변결 될 수 있습니다.

Multiple Worlds

위에서 설명한 기본 월드 외에 여러 개의 월드를 만들 수 있습니다. 둘 이상의 월드에서 동일한 구성 요소 시스템 클래스를 인스턴스화 할 수있으며, 각 인스턴스는 업데이트 순서의 서로 다른 지점에서 서로 다른 속도로 업데이트할 수 있습니다.

 

현재 특정 월드의 모든 시스템을 수동으로 업데이트할 수 있는 방법이 없습니다. 대신 월드에 생성되는 시스템과 기존 시스템 그룹을 제어할 수 있습니다. 따라서 사용자 지정 Wrold B는 System X및 Y를 인스턴스화 하여 System X를 기본 World의 SimulationSystemGroup에 추가하고 System Y를 기본 World의 PresentationSystemGroup에 추가할 수 있습니다. 이러한 시스템은 평소와 같이 그룹 형제를 기준으로 스스로를 주문 할 수 있으며 해당 그룹과 함께 업데이트됩니다.

 

이 사용 사례를 지원하기 위해 이제 새로운 IC 사용자 지정 부트스트랩 인터페이스를 사용할 수 있습니다.

public interface ICustomBootstrap
{
    // 기본 부트스트랩 프로세스에서 처리해야하는 시스템을 반환합니다.
    // null이 반환되면 기본 월드가 전혀 생성되지 않습니다.
    // 빈 목록은 기본 월드 및 진입점을 생성합니다.
    List<Type> Initialize(List<Type> systems);
}

이 인터페이스를 구현하면 기본 월드 초기화 전에 구성 요소 시스템 유형의 전체 목록이 클래스 Initialize() 메서드로 전달됩니다. 사용자 지정 부트스트래퍼는 이 목록을 반복하여 원하는 모든 환경에서 시스템을 생성할 수 있습니다. Initailize() 메서드에서 시스템 목록을 반환할 수 있으며 시스템 목록은 일반 기본 월드 초기화의 일부로 생성됩니다.

 

예를 들어 사용자 정의 MyCustomBootstrap.Initailize()의 일반적인 절차는 다음과 같습니다.  

  1.  additional Worlds and top-level ComponentSystemGroups을 만듭니다.
  2. For each Type in the system Type list:
    1. ComponentSystemGroup 계층 위로 이동하여 이 시스템 유형의 최상위 그룹을 찾습니다.
    2. 1단계에서 생성된 그룹 중 하나일 경우 해당 월드에서 시스템을 생성하고 group.AddSystemToUpdateList()를 사용하여 계층 구조에 추가하십시오.
    3. 그렇지 않을 경우, 이 유형을 목록에 추가하여 DefaultWorldInitialization으로 돌아갑니다.
  3. 새로운 최상위 그룹에 group.SortSystemUpdateList()를 호출하세요.
    1. 선택적으로 기본 세계 그룹 중 하나에 추가하십시오
  4.  처리되지 않은 시스템 목록을 DefaultWorldInitialization으로 반환합니다..

Note: the ECS framework finds your ICustomBootstrap implementation by reflection.

Tips and Best Practices

  • Use [UpdateInGroup] to specify the system group for each system you write. If not specified, the implicit default group is SimulationSystemGroup.
  • Use manually-ticked ComponentSystemGroups to update systems elsewhere in the Unity player loop. Adding the [DisableAutoCreation] attribute to a component system (or system group) prevents it from being created or added to the default system groups. You can still manually create the system with World.GetOrCreateSystem() and update it by calling manually calling MySystem.Update() from the main thread. This is an easy way to insert systems elsewhere in the Unity player loop (for example, if you have a system that should run later or earlier in the frame).
  • Use the existing EntityCommandBufferSystems instead of adding new ones, if possible. An EntityCommandBufferSystem represents a sync point where the main thread waits for worker threads to complete before processing any outstanding EntityCommandBuffers. Reusing one of the predefined Begin/End systems in each root-level system group is less likely to introduce a new "bubble" into the frame pipeline than creating a new one.
  • Avoid putting custom logic in ComponentSystemGroup.OnUpdate(). Since ComponentSystemGroup is functionally a component system itself, it may be tempting to add custom processing to its OnUpdate() method, to perform some work, spawn some jobs, etc. We advise against this in general, as it’s not immediately clear from the outside whether the custom logic is executed before or after the group’s members are updated. It’s preferable to keep system groups limited to a grouping mechanism, and to implement the desired logic in a separate component system, explicitly ordered relative to the group.
반응형