This document is about: QUANTUM 2
SWITCH TO

기타 사항

SDK 수정

FPS 템플릿은 기본 Quantum SDK와 다르게 여러 기능을 처리합니다.

기본 Quantum 및 FPS 템플릿 구현이 분기되는 모든 코드 경로는 QUANTUM_DEFAULT if-else 정의로 표시됩니다.

C#

#if QUANTUM_DEFAULT
    var matrix = Matrix4x4.TRS(t.position, t.rotation, t.localScale);
#else
    var matrix = Matrix4x4.TRS(t.position, t.rotation, t.lossyScale);
#endif

Quantum SDK

Quantum SDK와 비교하여 FPS 템플릿의 Quantum 시뮬레이션에서 변경된 사항은 다음과 같습니다.

  • 더 많은 매개 변수와 사용자 지정 처리를 가진 생성자를 지원하기 위해 FrameContextUser의 재정의
  • RuntimeConfig 크기 제한을 1kB에서 8kB로 증가
  • OnGameEnded()의 모든 시스템을 비활성화
  • 시스템(기본적으로 실행 가능하고 사용 가능) 및 특정 코드 경로에 대한 프로파일링 타이머 추가
  • 모든 기능을 지원하려면 우 특별한 경우 제외하고 frame.CreateEntity() 그리고 frame.DestroyEntity()를 통해 생성되고 제거되어야 합니다.
  • API 프레임에 컴포넌트와 컨트롤러를 가져오는 몇 가지 메소드 추가

Unity 통합

Quantum SDK에 포함된 것과 비교하여 FPS 템플릿의 유니티 측면의 변경 사항은 다음과 같습니다:

  • 자식과 소유자 엔티티 지원을 위한 확장된 엔티티 인스펙터.
  • MapData 컴포넌트 인스펙터와 Quantum > Bake > Prefabs 메뉴를 통한 Bake Prefabs의 추가 옵션.
  • 아키텍처가 다르기 때문에 일부 QuantumRunner함수(Init() 메소드 제외)를 무시하고 Simulator로 대체했습니다.주의: 여전히 상태 인스펙터와 같은 다른 도구들과 QuantumGame을 연결하는 데 사용됩니다.
  • 아키텍처가 다르기 때문에 EntityViewUpdater를 무시하고 Entities로 대체했습니다.
  • 아키텍처가 다르기 때문에 EntityView를 무시하고 Entity 컴포넌트로 대체했습니다.
  • EntityComponentBase는 사용자 지정 EntityComponent 스크립트를 상속합니다.
  • QuantumRunnerLocalDebugQuantumRunnerLocalReplay는 사용 불가입니다.
  • 아키텍처가 다르기 때문에 모든 기본 리플레이 스크립트를 사용자 지정 구현으로 교체했습니다.
  • QuantumStaticBoxCollider3D 그리고 QuantumStaticSphereCollider3D는 localScale 대신 lossyScale을 사용합니다.
  • 다양한 시나리오에 대한 트랜스폼 동기화 변형을 추가했습니다.
  • 엔티티는 기본적으로 항상 예측 프레임에서 생성되며, 검증된 프레임에서 산란하는 작업은 시뮬레이션에서 직접 처리해야 합니다.
  • SerializeReference] 특성을 가진 필드의 직렬화의 서버 측 역직렬화와의 서버 호환성을 위해 Newtonsoft.Json 대신 유니티 JsonUtility을 사용했습니다.

작업 흐름 권장 사항

다음 작업 흐름 권장 사항은 충돌을 방지하여 FPS 템플릿의 업데이트 및 업그레이드를 용이하게 하기 위한 것입니다.

  • 코드와 에셋은 각자의 핵심 환경(Framework / FPS / YOUR_PROJECT)에 따라 구성되도록 항상 노력합니다. 이는 유니티 및 Quantum 솔루션 모두에 적용됩니다.
  • 코어 Framework 코드를 수정하거나 확장할 경우 가능하면 부분 구현을 사용합니다. 대부분의 클래스 및 구조체는 해당 목적을 위해 부분 또는 부분적인 메소드를 가진 것으로 표시됩니다.
  • 엔티티를 만들기 위해 하드코딩된 문자열보다 항상 AssetRefEntityPrototype 필드를 선호합니다.
  • 모든 컨트롤러가 상태 비저장입니다. 롤백 할 수 없으므로 런타임에 필드를 수정하지 마십시오. 직렬화되지 않은 정적 속성을 캐싱 할 수 있지만 할당은 원자 오퍼레이션이어야 합니다. 그렇지 않으면 경합 조건이 다중 스레드 환경에 나타납니다.

유니티 엔진 사용

UnityEngine.dll은 서버 성능에 부정적인 영향을 미칠 수 있으므로 Quantum 솔루션과 연결할 수 없습니다. 그러나 DLL 하이재킹을 통해 데이터 구조와 속성을 사용하여 API를 모방할 수 있습니다.

동일한 서명을 가진 사용자 정의 UnityEngine.dll을 구축하는 방법에 대한 솔루션은 REPOSITORY/extras/UnityEngine에서 찾을 수 있습니다. 여기에는 데이터 구조와 속성이 포함되어 있으며 필요에 따라 수정할 수 있습니다. 솔루션을 구축하면 UnityEngine.dllREPOSITORY/assemblies로 복사됩니다. 이 라이브러리는 유니티에서 참조되지 않지만 원시 UnityEngine.dll은 참조됩니다.

서버에 사용자 지정 Quantum 플러그인을 업로드할 때 이 사용자 지정 UnityEngine.dll을 포함해야 합니다(엔터프라이즈 서버에서만 사용 가능, 주제에 대한 자세한 내용은 developer@photonengine.com 으로 문의하세요).

프레임워크 성능

다음은 저성능 모바일 장치에 대한 대상 구성 및 통계입니다:

  • 시뮬레이션 속도: 30 Hz
  • 목표 갱신 속도: 30 FPS
  • 하드 톨러런스: 7 frames (~230ms)
  • 지원 핑: ~250ms
  • 원시 충돌기: 500 (75% 박스)
  • 플레이어: 2 + 6 AI
  • 활성 발사체: 50
  • 사용자 지정 컨트롤러를 가진 기타 액터: 50
  • CPU 예산: 16.667ms (프레임의 50%)
  • GPU 예산: 16.667ms (프레임의 50%)
  • 시뮬레이션 예산: 4.167ms
  • 모든 기능이 활성화된 1개의 확인된 프레임의 시뮬레이션 시간: ~2.8ms
  • 모든 기능이 활성화된 예측 프레임 1개의 시뮬레이션 시간: ~1.1ms

1 유니티 프레임 동안, 게임은 평균 1개의 검증된 Quantum 프레임과 3 - 5개의 예측 Quantum 프레임을 계산하는데, 약 7 - 8ms가 소요됩니다. 최종 성능 수치는 사용된 실제 기능 세트에 따라 크게 달라집니다. 시뮬레이션 기반 자동 와이어를 사용하지 않고 간단한 AI를 구현하거나 절대적으로 필요한 시스템만 활성화하면 많은 성능을 절약할 수 있습니다.

플레이어 수도 중요한 요소입니다. 같은 게임 씬에서 플레이어의 수가 적을수록 로직은 더 비쌀 수 있고 그 반대의 경우도 마찬가지입니다. 이것은 빈 플레이어의 자리가 인공지능 액터들로 가득 찬다고 가정하는 것입니다.

예측 프레임(최대 40개)의 스파이크를 초래하는 네트워크 상태는 극히 드문 경우입니다. 그러나 저성능 장치에서는 이러한 문제를 쉽게 피할 수 없으며 성능 프로필의 설정을 고려해야 합니다.

디버깅

로깅

FPS 템플릿의 일부 하위 시스템에는 로그가 포함되어 있습니다. 이러한 로그를 사용하면 런타임에 발생하는 작업에 대한 자세한 정보를 볼 수 있습니다.

글로벌 수준의 로깅은 GameSettings 에셋의 Severity 속성을 통해 변경할 수 있습니다. 로그 그룹 재정의를 지정할 수도 있습니다.

game settings
Game Settings

또는 다음 API를 통해 런타임에 로깅 수준을 변경할 수 있습니다:

  1. 전역적으로: Log.SetSeverity(ELogSeverity.Warning);
  2. 로그 그룹 별로: Log.SetSeverity(ELogGroup.Matchmaking, ELogSeverity.Info);

비동기화

디버깅 상태 비동기화는 특히 일회성 작업이 많은 경우 간단한 프로세스가 아닙니다.

디버깅 프로세스를 원활하게 수행하기 위한 권장 사항은 다음과 같습니다:

  1. 안정적이고 빠르게 재생 가능한 비동기화가 가능한 상황을 찾으려고 노력하세요.
  2. 첫 번째, 중간 및 마지막 시스템에서 Quantum 시뮬레이션 내의 체크섬을 계산하고 기록합니다(검증된 프레임만!). 이를 통해 기준선이 제공됩니다.
  3. 체크섬 차이에 따라 새로운 간격 분할을 진행합니다. 새로운 첫 번째 시스템은 다음과 같습니다.
    • 체크섬이 마지막 시스템과 다른 경우 중앙 시스템을 사용합니다.
    • 체크섬이 중앙 시스템과 다른 경우 마지막 시스템을 선택합니다.
  4. 비동기화를 일으키는 시스템이 확인될 때까지 3단계를 반복합니다.
  5. 전체 프로세스를 엔티티 기준으로 적용하여 컴포넌트, 컨트롤러 또는 다른 시뮬레이션의 비동기화를 유발하는 측면을 분리합니다.

일반적인 문제점

  • 재시뮬레이션으로 인한 예측 엔티티 스폰 해제/재스폰: 유니티 쪽의 Entity.OnDeinitialize(bool silent) 그리고 EntityComponent.OnDeinitialize(bool silent)메소드에서 silent 부울을 토글 합니다. 엔티티가 확인될 때까지 페이딩 또는 스케일링 효과로 인해 사라짐 현상이 눈에 잘 띄지 않도록 하여 이 상황을 해결하는 것이 좋습니다.
  • Unknown managed type referenced: [quantum.code] Quantum.XYZController: 이 오류는 프리팹 또는 씬 게임 객체에 Quantum.XYZController 유형의 기존 직렬화된 인스턴스로 인해 발생합니다. 하지만 스크립트가 누락되었습니다. 일반적으로 스크립트를 제거하거나 이름을 바꾼 것과 관련이 있습니다. 이 문제를 해결하려면 오류를 트리거한 객체 / 직렬화된 파일을 찾아 해당 파일에서 직렬화된 데이터를 수동으로 제거하십시오 - 주의: 이 문제를 식별하고 해결하기 위한 툴이 포함되어 있지 않기 때문에 유니티 외부에서 수행해야 합니다. 또는 누락된 클래스를 일시적으로 다시 추가하면 필요한 객체를 다시 만들기 전에 다시 편집할 수 있습니다.
Back to top