This document is about: QUANTUM 2
SWITCH TO

컬링 예측

소개

컬링 예측은 플레이어가 특정 시간에 게임 세계를 부분적으로만 볼 수 있는 게임에서 사용됩니다. 사용하기에 안전하고 활성화가 간단합니다.

컬링 예측을 사용하면 Quantum 예측 및 롤백 단계에서 CPU 시간을 절약할 수 있습니다. 이 옵션을 활성화하면 로컬 플레이어에서 중요하고 가시적인 엔티티만을 위해 예측 변수를 실행할 수 있으며, 서버에서 입력을 확인한 후에는 뷰 밖의 아이템이 틱 당 한 번만 시뮬레이션되도록 할 수 있으므로 가능한 한 롤백 되지 않습니다.

게임마다 성능 이점은 다양하지만 상당히 클 수 있습니다. 이는 예측 변수가 적어도 한 명은 놓치게 되므로 더 많은 플레이어가 있을수록 특히 중요합니다.
30Hz 시뮬레이션 속도로 실행되는 게임을 예로 들어 보겠습니다. 게임이 검증된 입력당 평균 10개의 틱 롤백을 필요로 하는 경우, 게임 시뮬레이션은 300Hz(롤백 포함)에 가깝게 실행될 수 있을 만큼 가벼워야 합니다. 컬링 예측을 사용하면 항상 예상 30/60Hz에서 전체 프레임을 시뮬레이션하고 예측 버퍼 내에서 실행 중인 예측 영역에 컬링이 적용됩니다.

컬링 예측 설정하기

컬링 예측의 결과로 인해 예측된 시뮬레이션은 프레임의 일부가 컬링 되었기 때문에 프레임의 최종 결과로 결코 받아들여질 수 없으므로 전체 게임 상태의 시뮬레이션이 진전되지 않습니다.

컬링 예측을 설정하려면 Quantum과 유니티의 두 단계가 있습니다.

Quantum에서

Quantum에서 컬링 예측을 활성화하는 것은 다른 시스템보다 먼저 SystemSetup.cs에 컬링 시스템을 추가하는 간단한 방법입니다.

C#

namespace Quantum {
  public static class SystemSetup {
    public static SystemBase[] CreateSystems(RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
      return new SystemBase[] {
        // pre-defined core systems
        new Core.CullingSystem2D(), 
        new Core.CullingSystem3D(),
        
        new Core.PhysicsSystem2D(),
        new Core.PhysicsSystem3D(),
        
        new Core.NavigationSystem(),
        new Core.EntityPrototypeSystem(),

        // user systems go here
      };
    }
  }
}

기본적으로 Core.CullingSystem2D()Core.CullingSystem3D()SystemSetup에 포함되어 있습니다.

유니티에서

유니티에서는 예측 영역을 설정해야 합니다. 이 값은 예측에서 제거할 엔티티를 결정하는 데 사용됩니다.
유니티 업데이트 시마다 SetPredictionArea()를 호출하여 예측 영역을 업데이트할 수 있습니다.

C#

// center is either FPVector2 or FPVector3
// radius is an FP
QuantumRunner.Default.Game.SetPredictionArea(center, radius);

예상되는 것

물리 엔진 및 NavMesh 관련 시스템은 컬링 예측의 영향을 받습니다.

컬링 예측을 활성화하면 확인되지 않은 프레임(예측 프레임)의 가시 영역 내의 엔티티만 고려하고 업데이트합니다.

CPU 주기는 관련 컴포넌트(PhysicsCollider, PhysicsBody, NavMeshPathFinder, NavMeshSteeringAgent, NavMeshAvoidanceAgent)와 예측 센터 및 반지름에 의해 정의된 관심 영역 외부에 대한 업데이트를 건너뛰기 때문에 절약됩니다.

반복

또한 코드는 컬링 예측의 이점을 누릴 수 있습니다. Transform2D 또는 Transform3D를 포함하는 모든 필터는 위치에 따라 컬링 될 것입니다.

기본적으로 예측 프레임이 실행될 때마다 아래 메소드를 호출하면 예측 반지름의 제한 내에 있는 엔티티만 반환되며, 동일한 호출은 입력 확인 후 확인된 프레임을 시뮬레이션할 때 모든 활성 인스턴스를 반환합니다.

  • f.Filter()
  • f.Unsafe.FilterStruct()

주의: 컬링 예측으로 필터가 이득을 보는 반면, 컴포넌트 이터레이터그렇지 않습니다.

  • f.GetComponentIterator()
  • f.Unsafe.GetComponentBlockIterator()

수동 컬링 제어 플래그

프레임을 통해 제공되는 API를 통해 예측된 프레임에서 컬링 하기 위해 수동으로 엔티티들의 플래그를 조정할 수도 있습니다.

메소드 설명
SetCullable(EntityRef entityRef, bool cullable) 엔티티 참조가 잘못되었거나 엔티티가 존재하지 않는 경우 아무 작업도 수행하지 않습니다.
IsCulled(EntityRef entityRef) bool 리턴
True = 프레임 상태와 무관하게 엔티티가 컬링 될 수 있고 컬링 영역 내에 있는 경우
False = 엔티티가 컬링 되지 않거나 엔티티가 존재하지 않거나 엔티티 참조가 잘못된 경우
Culled(EntiyRef entityRef) bool 리턴
True = 엔티티가 컬링 될 수 있고 이 프레임에서 컬링 되고 있는 경우
False = 위에서 언급한 상태가 아닌 경우
Cull(EntiyRef entityRef) 이 틱에서 수동으로 엔티티를 컬링
ClearCulledState() 해당 프레임에 있는 모든 엔티티틔 컬링 상태를 재설정

일관된 상태를 유지하고 동기화가 되지 않는 상태를 방지하려면 de-flag 원래 플래그를 지정하는 것과 동일한 시스템에서 확인된 프레임에서 컬링 된 엔티티를 사용합니다. 따라서 일관된 상태를 유지하고 비동기화하지 않습니다.

RNG 문제없애기

컬링 예측과 함께 RNGSession 인스턴스를 사용하면 완벽하게 안전하며 결정론이 보장됩니다. 그러나 두 엔티티가 Quantum _globals_에 저장된 기본 엔티티와 같이 RNGSession을 공유하는 경우 두 엔티티가 함께 사용하면 일부 시각적으로 끊김 현상이 발생할 수 있습니다. 이는 검증된 프레임을 시뮬레이션한 후 예측된 엔티티에 대해 새로운 RNG 값이 생성되어 엔티티의 최종 위치를 변경/수정하기 때문입니다.

해결책은 컬링 대상이 되는 각 엔티티에 고립된 RNGSession 구조체를 저장하는 것입니다. 롤백을 위해 실제로 필요하지 않는 한 분리 보장은 예측된 엔티티의 최종 위치에 영향을 미치지 않습니다.

chsarp

struct SomeStruct {
    RNGSession MyRNG;
}

원하는 방식으로 각 RNGSession에 시드를 주입할 수 있습니다.

Back to top