Photon TrueSync 소개
시작하기
Photon TrueSync 는 Photon Unity 네트워킹 상단에 구축된 Unity용 멀티플레이어 완전동기화 시스템입니다.
TrueSync에서, 클라이언트 머신들은 각 플레이어들이 발생시킨 Input만 교환하고 시뮬레이션은 게임 클라이언트들 간의 lockstep에서 발생하므로 대역폭을 상당히 감소시키면서 완전 동기화를 할 수 있습니다.
TrueSync에는 커스텀 물리 엔진이 포함되어 있으며 개발 지원을 위한 각 머신간의 시뮬레이션 결정을 유지해 줄 수 있는 클래스가 포함되어 있습니다.
역주:결정론적 시스템(Deterministic system) : 정해진 입력값을 어떤 시스템에 넣으면 그 입력에 맞는 예측 가능한 출력이 나오는 시스템
TrueSync 는 Unity가 지원하는 대부분의 모든 플랫폼에 엑스포트 됩니다.
약간의 코딩이 필요합니다
TrueSync를 최대한으로 활용하려면 스크립트 작성이 필요합니다.
이 페이지에서는 시작할 때 가장 중요한 부분에 대해 설명하고 있습니다.
TrueSync 결정론적 섹션 시작
TrueSync 섹션은 PUN(Photon Unity Network)룸에 연결된 게임 클라이언트간에서 발생하므로 룸을 설정하고 생성/참여하는 방법에 대한 문서를 참조 해주세요.
실제 TrueSync 매니지드 게임플레이 섹션은 TrueSyncManager
컴포넌트가 게임 오브젝트에 연결된 것이 있는 신이 PUN 을 통해 동기화 로드될 때 마스터-클라이언트에 의해 시작됩니다.
TrueSyncManager
는 멀티플레이어 완전동기화 섹션이 시작되어야 하는 시점인 게임클라이언트의 룸 연결 여부를 체크합니다.
시스템이 오프라인 모드로 동작하는 경우에는 PUN 룸에 접속하지 않고 TrueSyncManager를 사용할 수 있습니다. 이 특징은 싱글-플레이어 게임에서 동일한 코드와 컴포넌트들을 (재)사용하는데 아주 좋습니다.
Input 큐에 넣기
Lockstep 시스템에서 로컬 플레이어의 input 은 게임플레이 코드에서 사용 하기전 먼저 큐에 들어가야 합니다.
이렇게하면 시스템은 원격 플레이어의 입력을 기다리고 큐에 들어간 로컬 입력과의 사용을 동기화 할 수 있습니다.
C#
public override void OnSyncedInput () {
FP x = Input.GetAxis("Horizontal");
TrueSyncInput.SetFP(0, x);
}
플레이어 input을 로컬과 리모트 클라이언트들에서 모두 사용 할 수 있도록 TrueSync 입력 큐에 등록하려면 위에 있는 코드만 작성하면 됩니다.
첫 번째 파라미터는 필요한 키 만큼 여러 input 값을 등록 할 수 있습니다.
float 를 FixedPoint (FP) 로 변환해야 한다는 점에 주의해주세요.
Float 형은 아키텍처마다 동일한 방식으로 정확하게 계산되지 않으므로, 모든 클라이언트 사이에서 동기화 시뮬레이션을 맞추어 주어야 하므로 형 변환이 필요합니다.
게임상태 갱신을 위한 input 사용
그 다음으로 Unity의 다른 게임처럼 input 값은 게임 오브젝트 갱신을 위해 사용합니다.
차이점은 직접 Unity 에서 가져오느냐 아니면 TureSync 큐 시스템에서 가져오느냐는 것 입니다.
C#
public override void OnSyncedUpdate () {
TSVector move = new TSVector(TrueSyncInput.GetInt(0), 0, 0);
tsTransform.Translate(move * TrueSyncManager.DeltaTime);
}
위의 코드에서 TSVector 클래스도 있는데 이 클래스는 Unity의 Vector3 클래스와 완전 동일하나 x,y 와 z 의 float 대신 FP 를 사용합니다.
또한 Unity의 delta-time 이 아닌 TrueSync의 delta-time을 사용하고 있다는 것도 주의해주세요.
물리
TrueSync에는 2D 게임용 그리고 3D 게임용 2개의 커스텀 물리엔진이 있습니다.
두 엔진 모두 Unity의 물리 엔진과 아주 유사한 컴포넌트 아키텍처와 API들을 사용하고 있습니다.
TrueSync 에는 이 물리엔진에 대한 사용방법을 보여주는 몇 개의 게임 샘플이 포함되어 있습니다.
아래의 코드는 물리 rigidbody 의 TrueSync의 결정론적 버전으로, 강제로 TSRigidbody 에 어떻게 적용시키는지 보여주는 코드입니다.
C#
public override void OnSyncedUpdate () {
TSRigidBody rb = GetComponent<TSRigidBody>();
rb.AddForce(TSVector.forward * TrueSyncManager.DeltaTime);
}
충돌과 트리거는 Unity 물리와 상응하고 유사하게 동작하지만 모든 콜백 메소드는 "OnSynced" 로 시작하여 이 의미는 TrueSync의 결정 물리엔진에서 호출 되었다는 것입니다.
C#
public void OnSyncedCollisionEnter(GameObject other) {
Destroy(other);
}