수정중인 페이지 입니다.

Fusion 헤드리스 모드

이 문서에서는 헤드리스 유티니 애플리케이션에서 Photon Fusion을 시작하는 데 사용할 수 있는 유틸리티 스크립트 집합을 설명합니다. 그래픽 인터페이스 없이 Fusion을 시작할 때 특별한 것은 없으며 이러한 스크립트는 하나의 방법일 뿐입니다.

HeadlessController 스크립트

다음은 서버 게임 모드에서 새로운 Fusion 러너를 인스턴스화하고 시작하는 스크립트입니다. HeadlessUtils 스크립트(아래 참조)를 사용하여 바이너리가 "헤드리스 모드"에서 시작되었는지 확인하고 로드해야 할 씬도 확인합니다. 게임 서버를 초기화하는 동안 오류가 발생하면 애플리케이션은 외부 애플리케이션에서 확인하는 데 유용한 0이 아닌 종료 코드를 사용하여 종료됩니다.

using UnityEngine;
using Fusion;
using System.Collections.Generic;
using Fusion.Sockets;
using UnityEngine.SceneManagement;

public class HeadlessController : MonoBehaviour, INetworkRunnerCallbacks {

  [SerializeField]
  private NetworkRunner _runnerPrefab;

  void Awake() {
    Application.targetFrameRate = 30;
  }

  async void Start() {

    // Quit if not in Headless mode
    if (HeadlessUtils.IsHeadlessMode() == false) {
      Application.Quit(1);
    }

    // Get game scene to be loaded
    var sceneToLoad = HeadlessUtils.GetArg("-scene") ?? SceneManager.GetActiveScene().name;

    Debug.Log($"Starting Server");

    // Create a new Fusion Runner  
    var runner = Instantiate(_runnerPrefab);

    // Basic Setup
    runner.name = $"DedicatedServer";
    runner.AddCallbacks(this); // register callbacks

    // Start the Server
    var result = await runner.StartGame(new StartGameArgs() {
      GameMode = GameMode.Server, // for dedicated servers,
      Scene = SceneManager.GetSceneByName(sceneToLoad).buildIndex,
      SceneObjectProvider = gameObject.AddComponent<NetworkSceneManagerDefault>()
    });

    // Check if all went fine
    if (result.Ok) {
      Debug.Log($"Runner Start DONE");
    } else {
      // Quit the application if startup fails

      Debug.LogError($"Error while starting Server: {result.ShutdownReason}");

      // it can be used any error code that can be read by an external application
      // using 0 means all went fine
      Application.Quit(1);
    }
  }

  // Fusion INetworkRunnerCallbacks implementation

  public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) {
    Debug.LogWarning($"{nameof(OnShutdown)}: {nameof(shutdownReason)}: {shutdownReason}");

    // Quit normally
    Application.Quit(0);
  }

  public void OnPlayerJoined(NetworkRunner runner, PlayerRef player) => Debug.LogWarning($"{nameof(OnPlayerJoined)}: {nameof(player)}: {player}");
  public void OnPlayerLeft(NetworkRunner runner, PlayerRef player) => Debug.LogWarning($"{nameof(OnPlayerLeft)}: {nameof(player)}: {player}");
  public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token) => Debug.LogWarning($"{nameof(OnConnectRequest)}: {nameof(NetworkRunnerCallbackArgs.ConnectRequest)}: {request.RemoteAddress}");
  public void OnSceneLoadDone(NetworkRunner runner) => Debug.LogWarning($"{nameof(OnSceneLoadDone)}: {nameof(runner.CurrentScene)}: {runner.CurrentScene}");
  public void OnSceneLoadStart(NetworkRunner runner) => Debug.LogWarning($"{nameof(OnSceneLoadStart)}: {nameof(runner.CurrentScene)}: {runner.CurrentScene}");
  public void OnInput(NetworkRunner runner, NetworkInput input) { }
  public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input) { }
  public void OnConnectedToServer(NetworkRunner runner) { }
  public void OnDisconnectedFromServer(NetworkRunner runner) { }
  public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason) { }
  public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message) { }
  public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList) { }
  public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
  public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, System.ArraySegment<byte> data) { }
}

메인 화면으로

HeadlessUtils 스크립트

이 스크립트는 유니티 바이너리가 "헤드리스 모드"(IsHeadlessMode)에서 시작되었는지 확인하고 특정 명령 줄 인수(GetArg)의 값을 가져오는 데 사용할 수 있는 두 가지 방법만 포함하고 있으며 사용자 지정 시작 설정을 헤드리스 게임 서버에 전달하는 데 유용합니다.

using System;

public class HeadlessUtils {

  /// <summary>
  /// Signal if the executable was started in Headless mode by using the "-batchmode -nographics" command-line arguments
  /// <see cref="https://docs.unity3d.com/Manual/PlayerCommandLineArguments.html"/>
  /// </summary>
  /// <returns>True if in "Headless Mode", false otherwise</returns>
  public static bool IsHeadlessMode() {
    return Environment.CommandLine.Contains("-batchmode") && Environment.CommandLine.Contains("-nographics");
  }

  /// <summary>
  /// Get the value of a specific command-line argument passed when starting the executable
  /// </summary>
  /// <example>
  /// Starting the binary with: "./my-game.exe -map street -type hide-and-seek"
  /// and calling `var mapValue = HeadlessUtils.GetArg("-map", "-m")` will return the string "street"
  /// </example>
  /// <param name="keys">List of possible keys for the argument</param>
  /// <returns>The string value of the argument if the at least 1 key was found, null otherwise</returns>
  public static string GetArg(params string[] keys) {
    var args = Environment.GetCommandLineArgs();

    for (int i = 0; i < args.Length; i++) {
      foreach (var name in keys) {
        if (args[i] == name && args.Length > i + 1) {
          return args[i + 1];
        }
      }
    }

    return null;
  }
}


기술문서 TOP으로 돌아가기