수정중인 페이지 입니다.

호스트 마이그레이션 API

소개

Photon Fusion은 서버를 실행하는 방법과 위치, 그리고 필요한 경우 여러 가지 아키텍처를 지원합니다. 이러한 아키텍처 중 하나는 클라이언트 호스팅 토폴로지로, 기본적으로 게임을 플레이하는 플레이어 중 한 명이 게임 호스트 역할을 겸하도록 구성되어 있습니다. 즉, 로컬 컴퓨터에서 새로운 게임 세션을 만들고 서비스하며 다른 사용자가 세션 서버로 컴퓨터를 사용하여 연결하고 함께 플레이할 수 있도록 합니다. Fusion은 클라이언트 간의 모든 기본 연결을 처리하는 NAT 펀치쓰루 알고리즘을 구현하므로 포트 포워딩 또는 방화벽을 설정할 필요가 없습니다. Fusion은 이를 자동으로 처리하여 홈 기반 호스팅 된 게임을 매우 쉽게 구축할 수 있습니다.

게임 호스트를를 네트워크 백단에서 실행할 때의 주요 단점 중 하나는 이러한 유형의 네트워크가 클라이언트와의 원활한 통신을 위해 트래픽을 처리하는 데 적합하지 않다는 것입니다. 호스트가 오프라인으로 전환될 수 있고, 게임 서비스를 견딜 수 없는 다른 이유 중 하나에서 컴퓨터의 전원이 꺼질 수 있습니다. 이 경우 나쁜 경험이 발생할 수도 있지만, Fusion 기반 게임은 게임 서버가 있는 경우에만 실행될 수 있기 때문에 최종적으로는 게임이 종료됩니다.

이러한 이유로 Fusion은 호스트 마이그레이션 시스템도 구현합니다. 이 시스템은 이러한 순간이 발생하면 호스트가 게임을 계속 서비스할 수 없으며 게임을 계속하려면 다른 피어가 새 호스트로 이어받아야 합니다. 이는 게임 자체의 전반적인 경험에 매우 유용하며 전용 서버 아키텍처의 대안으로 작용합니다.

이 페이지에서는 Fusion 호스트 마이그레이션 API에 대해 설명합니다.

노트: 구현 예제는 Fusion 호스트 마이그레이션 샘플에서 찾아보실 수 있습니다.

메인 화면으로

호스트 마이그레이션

호스트 마이그레이션을 수행하기 위해서는 프로젝트가 몇 가지 필수 구성 요소를 충족해야 합니다.

  1. 호스트 기반 게임: Fusion을 시작할 때 피어 중 하나가 호스트 모드(동일 컴퓨터의 서버 + 플레이어)에서 시뮬레이션을 시작해야 합니다. 이 작업은 GameMode.Host 또는 GameMode.AutoHostOrClient을 사용하여 Fusion Simulation(NetworkRunner.StartGame)을 시작하여 수행할 수 있습니다.
  2. 호스트 마이그레이션 사용: 이 기능은 필수 기능이 아니며 일부 수동 작업이 필요하므로 기본적으로 사용하도록 설정되어 있지 않습니다. 활성화 방법은 아래를 참조하십시오.
  3. 마이그레이션을 위한 게임 준비: 호스트를 다른 시스템으로 마이그레이션하는 것은 쉬운 작업이 아니지만 Fusion을 통해 최대한 간편하게 수행할 수 있습니다. 이 시스템은 이전 모든 호스트 게임 상태에 접근할 수 있지만 마이그레이션 내에서 들어오고 나가는 것을 강제하지 않기 때문에 충분히 유연합니다.

메인 화면으로

호스트 마이그레이션 활성화

호스트 마이그레이션을 사용하려면 Fusion/Network Project Config 메뉴를 통해 NetworkProjectConfig를 열고 Config 섹션에서 다음 설정을 확인하십시오.

  • 호스트 마이그레이션 사용: 호스트 마이그레이션 시스템을 사용하도록 설정하려면 확인란을 선택합니다.
  • 호스트 마이그레이션 스냅샷 간격: Photon Cloud로 전송되는 각 스냅샷 간의 간격(초)으로, 최신 스냅샷만 저장됩니다. 여기에 합리적인 값을 사용하는 것이 좋습니다, 30초 미만은 게임에 따라 너무 공격적일 수 있습니다. 호스트가 최종 사용을 위해 Photon Cloud에 스냅샷을 전송하므로 전체 게임 환경에 영향을 미치지 않습니다. 호스트를 마이그레이션해야 하는 경우 최근 게임 상태가 손실되는 것은 예상보다 커야 합니다.

메인 화면으로

호스트 마이그레이션 수행

호스트 마이그레이션 프로세스의 중심점은 INetworkRunnerCallbacks.OnHostMigration 콜백에서 발생합니다. 게임이 호스트 마이그레이션 절차를 수행해야 할 때 호출됩니다. 마이그레이션 프로세스는 Fusion이 NetworkObjects 목록을 통해 이전 호스트 게임 상태를 노출하는 조건으로 부분 수동 및 부분 자동입니다. 이 목록은 반복할 수 있으며 이전 버전에서 가능한 한 가깝게 게임 플레이를 재구성할 수 있도록 데이터를 수집합니다.

호스트 마이그레이션 프로세스는 다음 단계와 같이 설명할 수 있습니다:

  1. Fusion이 호스트가 세션을 떠난 것을 감지하면 다른 모든 피어에서 호스트 마이그레이션 프로세스를 트리거 합니다. 이때, 새로운 호스트를 임의로 선택하여 이전 호스트가 보낸 마지막 저장 게임 상태를 전송합니다. 다른 피어는 이 상태 스냅샷을 수신하지 않으며 새 호스트만 수신합니다.
  2. INetworkRunnerCallbacks.OnHostMigration 콜백이 호출되면 마이그레이션 프로세스가 수행되어야 함을 알립니다.
  3. 현재 Fusion Runner는 여전히 실행 중이며 수동으로 종료해야 합니다. 이는 개발자가 마이그레이션 자체를 수행하기 전에 사전 설정을 처리할 수 있도록 하기 위함입니다.
  4. 게임을 다시 시작하려면 새로운 Fusion NetworkRunner를 만들어야 하며, 오래된 Runner를 재사용할 수 없습니다. 이전 게임에 대한 모든 필요한 정보는 OnHostMigration 콜백과 함께 제공되는HostMigrationToken으로 전달됩니다. 이 단계는 클라이언트와 새 호스트에서 모두 발생하며, 특정 피어가 사용하는 GameModeSessionName과 같은 HostMigrationToken.GameMode에 지정되어 있습니다. 두 아규먼트는 마이그레이션을 행할 때 모두 무시됩니다.
  5. 마지막 단계는 게임 재생성으로, 새로운 호스트에서만 발생하며 Fusion이 HostMigrationResume 인수에 전달된 콜백을 호출하는 것으로 구성됩니다. 이 콜백은 Runner가 완전히 시작되기 전에 호출되며 개발자가 이전 게임 상태를 읽고, 이전 NetworkObject를 다시 만든 후 필요에 따라 설정할 수 있습니다.

다음 코드는 위의 단계를 보여 줍니다:

public class FusionInit : MonoBehaviour, INetworkRunnerCallbacks {

  // other callbacks...

  // Step 1.
  // It happens on the Photon Cloud and there is no direct relation with the code on the peers.

  // Step 2.
  // OnHostMigration callback
  public async void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) {

    // Step 3.
    // Shutdown the current Runner, this will not be used anymore. Perform any prior setup and tear down of the old Runner

    // The new "ShutdownReason.HostMigration" can be used here to inform why it's being shut down in the "OnShutdown" callback
    await runner.Shutdown(shutdownReason: ShutdownReason.HostMigration);

    // Step 4.
    // Create a new Runner.
    var newRunner = Instantiate(_runnerPrefab);

    // setup the new runner...

    // Start the new Runner using the "HostMigrationToken" and pass a callback ref in "HostMigrationResume".
    StartGameResult result = await newRunner.StartGame(new StartGameArgs() {
      // SessionName = SessionName,              // ignored, peer never disconnects from the Photon Cloud
      // GameMode = gameMode,                    // ignored, Game Mode comes with the HostMigrationToken
      HostMigrationToken = hostMigrationToken,   // contains all necessary info to restart the Runner 
      HostMigrationResume = HostMigrationResume, // this will be invoked to resume the simulation
      // other args
    });

    // Check StartGameResult as usual
    if (result.Ok == false) {
      Debug.LogWarning(result.ShutdownReason);
    } else {
      Debug.Log("Done");
    }
  }

  // Step 5. 
  // Resume Simulation on the new Runner
  void HostMigrationResume(NetworkRunner runner) {

    // Get a temporary reference for each NO from the old Host
    foreach (var resumeNO in runner.GetResumeSnapshotNetworkObjects())

      if (
          // Extract any NetworkBehavior used to represent the position/rotation of the NetworkObject
          // this can be either a NetworkTransform or a NetworkRigidBody, for example
          resumeNO.TryGetBehaviour<NetworkPositionRotation>(out var posRot)) {

          runner.Spawn(resumeNO, position: posRot.ReadPosition(), rotation: posRot.ReadRotation(), onBeforeSpawned: (runner, newNO) => 
          {
            // One key aspects of the Host Migration is to have a simple way of restoring the old NetworkObjects state
            // If all state of the old NetworkObject is all what is necessary, just call the NetworkObject.CopyStateFrom
            newNO.CopyStateFrom(resumeNO);

            // and/or

            // If only partial State is necessary, it is possible to copy it only from specific NetworkBehaviours
            if (resumeNO.TryGetBehaviour<NetworkBehaviour>(out var myCustomNetworkBehaviour))
            {
               newNO.GetComponent<NetworkBehaviour>().CopyStateFrom(myCustomNetworkBehaviour);
            }
          });
      }
    }
  }

  public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) {

    // Can check if the Runner is being shutdown because of the Host Migration
    if (shutdownReason == ShutdownReason.HostMigration) {
      // ...
    } else {
      // Or a normal Shutdown
    }
  }
}

메인 화면으로

완전한 API

  • INetworkRunnerCallbacks.OnHostMigration: 콜백은 호스트 마이그레이션을 수행해야 할 때 호출됩니다.
  • HostMigrationToken: 호스트 마이그레이션을 수행할 때 이전 NetworkRunner의 모든 필요한 정보가 포함되어 있으며 StartGame을 실행할 때 새로운 NetworkRunner로 전달되어야 합니다.
  • HostMigrationToken.GameMode: 새로운 GameMode로컬 피어는 Host 또는 Client가 될 수 있으므로 시작합니다. 플레이어에게 추가 정보를 표시하는 데 유용합니다.
  • StartGameArgs.HostMigrationToken: INetworkRunnerCallbacks.OnHostMigration 콜백의 아규먼트로서 HostMigrationToken을 받습니다.
  • StartGameArgs.HostMigrationResume: 새 호스트에서 시뮬레이션 다시 만들기를 수행할 때 호출되는 콜백을 수락합니다.
  • NetworkRunner.GetResumeSnapshotNetworkObjects: 이전 호스트의 마지막으로 알려진 상태를 나타내는 NetworkObjects의 반복 가능한 목록을 반환합니다. 새 Fusion Simulation에서 다시 생성해야 할 항목을 확인하는 데 사용할 수 있습니다.
  • NetworkObject.CopyStateFrom: 이전 NetworkObject에서 새로 생성된 NetworkObject로 모든 상태를 복사하는 데 사용됩니다.
  • NetworkBehaviour.CopyStateFrom: 특정 NetworkBehaviour에서 새로운 NetworkObject로 모든 상태를 복사하는 데 사용합니다.
  • ShutdownReason.HostMigration: 이 새로운 ShutdownReasonNetworkRunner가 종료되고 마이그레이션에 적절하게 반응하는 데 사용되는 이유를 나타내는 데 사용될 수 있습니다.

기술문서 TOP으로 돌아가기