수정중인 페이지 입니다.

Matchmaking API

개요

멀티플레이어 게임을 만들 때 필요한 핵심 요구사항 중 하나는 유사한 기술이나 레벨을 가진 플레이어 또는 동일한 게임 유형 또는 맵을 원하는 플레이어들을 쉽게 매칭하여 게임 내 전반적인 경험을 최대한 즐겁게 만드는 것입니다. 이를 위해, Photon Fusion은 완벽한 매치를 찾는 플레이어들에게 최상의 경험을 제공하는 데 사용할 수 있는 API들을 제공합니다.

Photon Fusion은 Photon Cloud와 명백하게 연동되기 때문에 Photon 백엔드 서비스와의 상호작용은 대부분 내부적으로 자동으로 이루어집니다. 이 페이지에는 플레이어가 원하는 게임 플레이 경험을 바탕으로 최고의 Session에 참여/필터링할 수 있는 사용자 지정 속성으로 게임 세션을 생성/업데이트하는 데 사용되는 Fusion 매치메이킹 API가 설명되어 있습니다.

메인 화면으로

게임 세션을 생성하고 참여하기

게임 세션의 생성과 참여는 동일한 프로시저의 두 부분으로, 규칙은 간단합니다: 1. 지정된 이름을 가진 세션이 없는 경우 해당 이름을 가진 새 세션(아래 설명과 같은 모든 경우는 아님)이 생성되며 2. 피어가 해당 이름의 세션에 참여합니다.

API 측면에서 이 모든 것은 새로운 Fusion 시뮬레이션이 시작될 때 자동으로 수행되며, 아래에 새 인수를 만들 때 세션을 사용자 지정하는 데 사용할 수 있는 주요 인수가 나와 있습니다:

NetworkRunner.StartGame(new StartGameArgs {
  // other args...
  SessionName = [string]
  SessionProperties = [Dictionary<string, int>],
  CustomLobbyName = [string]
});

모든 게임 세션 관련 아규먼트는 선택적이며 각각의 기본값은 아래에 설명되어 있습니다:

  • SessionName: 게임 세션이름, Photon Cloud에서 세션을 식별하며 지역내에서 유일해야 합니다. 기본적으로, Name이 설정되어 있지 않으면 다음의 두 가지 경우가 가능합니다:
    1. 특정 SessionName으로 시작할 때 Fusion은 항상 해당 Name으로 Session을 생성/조인하려고 시도합니다. Fusion에 대한 중요한 사실은 클라이언트 피어가 세션을 만들 수 있다는 것입니다. 즉, Late-join-server라고 합니다. 여기서 서버클라이언트에 의해 만들어진 세션에 미리 가입할 수 있습니다.
    2. SessionName을 지정하지 않았을 때, Host, Server, 또는 공유 게임 모드에서 시작한 경우에는 Fusion이 새로운 세션을 생성/참여할 것이고, Client 모드에서 시작한 경우이면 무작위 Session에 참여하려고 할 것입니다.
  • SessionProperties: 세션사용자 지정 속성은 게임 모드/유형 또는 현재 로드된 맵과 같은 게임 세션에 대한 메타데이터를 포함하는 방법입니다. 세션을 생성할 때 속성은 항상 세션 로비에 게시됩니다. 또 다른 용도는 클라이언트가 임의의 세션에 참여할 때 이 아규먼트가 일치하는 필터인 경우입니다. 트래픽을 최소화하기 위해 항상 속성 키 문자열을 최대한 짧게 유지하는 것이 좋습니다. 기본적으로 세션 사용자 지정 속성은 비어 있으며 추가 정보가 포함되지 않습니다.
  • CustomLobbyName: 로비는 예를 들자면 게임 종류가 다른 세션을 분리하는 데 사용할 수 있는 유사한 게임 세션을 통합하는 방법에 지나지 않습니다. 이 인수는 세션이 연결될 사용자 정의 로비 이름을 설정하기 위해 사용됩니다. 기본적으로 Fusion은 호스트, 서버, 클라이언트 게임 모드에서 세션을 생성한 경우 클라이언트서버 로비 또는 공유 게임 모드에서 생성된 경우 공유 로비에서 게임 모드를 기반으로 세션을 구분합니다.

이 API를 사용하면 게임 초대를 받을 때 사용할 수 있는 게임 세션을 무작위로 생성하거나 특정 이름으로 참여시킬 수 있지만, 사용자 지정 속성을 이용한 세션 필터링도 가능하여 특정 구성의 게임에만 참여할 수 있습니다. 따라서 세션을 관리할 때 이미 많은 유연성을 제공합니다.

시뮬레이션 시작 시 세션 이름GameMode에 따라 Fusion이 게임 세션 생성 및 참여를 처리하는 방식이 다음 표에 요약되어 있습니다.

유효 세션 이름 GameMode Behavior
Yes 호스트/서버 세션 생성
클라이언트 세션 참여 또는 찾지 못하는 경우 실패
공유 세션 참여 또는 찾지 못하는 경우 실패
No 호스트/서버 무작위 이름으로 세션 생성
클라이언트 무작위 세션 참여 또는 찾지 못하는 경우 실패
공유 무작위ㅡ 세션 참여 또는 찾지 못하는 경우 무작위 이름으로 세션 생성

메인 화면으로

게임 세션 정보를 가져오고 업데이트

Fusion은 이름, 지역 등 현재 연결된 게임 세션에 대한 많은 정보를 제공합니다. 이러한 데이터는 SessionInfo 속성을 통해 NetworkRunner에서 직접 사용할 수 있습니다. 다음은 SessionInfo 타입의 사용 가능한 모든 필드입니다:

  • IsValid [bool{get}]: SessionInfo가 읽고 쓸 준비가 된 경우 신호
  • Name [string{get}]: 세션 이름;
  • Region [string{get}]: 현재 연결된 지역;
  • Properties [Dictionary<string, int>{get}]: 현재의 세션 사용자 지정 속성의 읽기 전용 딕셔너리. 이러한 속성들을 업데이트 하기 위해서, SessionInfo.UpdateCustomProperties(Dictionary<string, int>) 메소드를 사용하고 속성의 새로운 집합을 전달합니다.
  • IsVisible [bool{get,set}]: 로비에서 세션이 보여지는 경우 신호. Session 을 보이지 않도록 하려면 이 속성을 변경하면 됩니다.
  • IsOpen [bool{get,set}]: 세션이 참여하기 위해 오픈된 경우 신호. 세션을 닫거나 오픈하기 위해서 이 속성만 변경합니다.
  • PlayerCount [int{get}]: 현재 세션내에 있는 플레이어의 수. 로비에서만 사용할 수 있습니다
  • MaxPlayers [int{get}]: 세션에 참여할 수 있는 피어의 최대 수. 이 값은 서버/호스트 피어의 슬롯을 포함하고 있습니다. 로비에서만 사용가능합니다.

예를들어 세션 정보와 사용자 지정 속성은 주로 게임 상태 정보는 매치메이킹 목적으로만 사용해야 하고 예를들어 게임 클라이언트와 동기화하기 위한 사용은 절대로 사용하지 마세요. 이러한 사용은 권고하지 않습니다. 게임 플레이와 관련된 정보를 세션 전반에서 교환해야 하는 경우 Fusion은 글로벌 NetworkObject를 사용하거나 원샷 데이터에 RPC를 사용하는 등 다양한 옵션을 제공합니다.

메인 화면으로

로비에서 게임 세션에 참여하기

올바른 게임 세션을 찾는 또 다른 방법은 세션 목록을 제공하여 플레이어가 선택하여 참여할 수 있도록 하는 것입니다. 이 경우를 통해 로비에 참여할 수 있는 방법이긴 하지만, 정말 필요하지 않다면 이 방법을 피하는 것이 좋습니다. 대부분의 게임 유형에서는 속성 필터를 기반으로 세션에 참여하는 것이 가장 좋지만, 퓨전에서는 세션 리스팅도 쉽게 할 수 있습니다.

위에서 설명한 것처럼 일반적인 흐름을 사용하고 Fusion을 시작하는 대신 세션 목록은 약간 다른 흐름을 따릅니다:

  1. 로비 참여: Fusion 러너 참조를 사용하여, 로컬 피어가 Photon Cloud에 접속하고 로비에 참여하기 위해 NetworkRunner.JoinSessionLobby(SessionLobby, [string])만 호출하면 됩니다. 이 메소드는 2개의 아규먼트를 받습니다:
    • SessionLobby: 다음 중 하나의 값이 될 수 있습니다:
      1. 기본 ClientServer Lobby에 참여하기 위한 ClientServer
      2. 기본 Shared Lobby에 참여하기 위한 Shared
      3. Custom, 사용자 지정 로비 이름과 함께 사용.
    • LobbyName: 이전 게임 세션을 만들 때 사용하는 사용자 지정 로비 이름이어야 합니다.
  2. 게임 세션의 목록 얻기: Fusion에서 작업할 때 주요 API 진입점 중 하나는 Fusion이 로비의 세션 목록을 포함하여 일련의 다른 이벤트를 표시하기 위해 사용하는 특수 인터페이스인 INetworkRunnerCallbacks입니다. OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList) 콜백은 세션 목록이 변경될 때마다 세션 생성/삭제 또는 세션 속성 업데이트 시 호출됩니다. SessionInfo는 위에서 설명한 것과 같은 타입입니다. 그런 다음 목록을 표시하고 필터링하거나 순서를 지정할 수 있습니다.
  3. 세션 참여: 선택한 세션에 참여하면 NetworkRunner.StartGame(GameMode, SessionInfo) 오버로드를 사용하여 Fusion을 시작할 수 있습니다. 이 메소드는 두 개의 아규먼트를 수신합니다:
    • GameMode: 이는 Fusion 시뮬레이션을 시작할 때 사용하는 것과 동일한 GameMode이지만, 이미 존재하는 세션 에 참여할 때 사용되는 것이므로 메소드는 GameMode.Client 또는 GameMode.Shared 모드만 받습니다.
    • SessionInfo: 세션 목록으로부터의 SessionInfo 참조입니다. 세션 목록에서 참조한 정보를 넘기면 Fusion이 해당 세션에 참여할 수 있습니다.

메인 화면으로

API 사용법 예제

사용자 지정 속성으로 새로운 게임 세션 시작

이 예제에서는 Host가 일부 사용자 지정 속성값으로 게임 세션을 생성합니다. 이후 클라이언트는 이러한 속성들을 사용하여 세션을 필터링할 수 있습니다.

// Some predefined types used as values for the Game Session Properties
public enum GameType : int {
  FreeForAll,
  Team,
  Timed
}

public enum GameMap : int {
  Forest,
  City,
  Desert
}

// Utility method to start a Host using a defined GameMap and GameType
public async Task StartHost(NetworkRunner runner, GameMap gameMap, GameType gameType) {

  var customProps = new Dictionary<string, int>();

  customProps["map"] = (int)gameMap;
  customProps["type"] = (int)gameType;

  await runner.StartGame(new StartGameArgs() {
    GameMode = GameMode.Host,
    SessionProperties = customProps,
  });
}

샘플 코드는 게임 세션사용자 지정 속성 값에 Enums를 사용하는 것을 보여주지만, 이는 값에 의미를 더하는 한 가지 방법에 불과합니다. 호스트 (GameMode = GameMode.Host)로써 runner.StartGame을 호출하는 것은 무작위 이름 (SessionName 아규먼트가 전달되지 않았기 때문에)으로 새로운 세션을 시작하는 것이 충분하며 SessionProperties 아규먼트를 사용하여 Fusion은 세션에 이러한 속성들을 포함하게 됩니다.

메인 화면으로

필터링으로 무작위 세션에 참여

위의 예제 코드를 염두에 두고, 다음은 특정 GameType으로 지정하고, 모든 GameMap, 모든 Game Session으로 참여하는 클라이언트의 시작 방법을 알 수 있습니다. 시작 코드는 기본적으로 동일하며 현재 GameModeGameMode.Client으로 설정되고 customProps이 원하는 gameType 값으로 type 키만 포함하고 있습니다.

public async Task StartClient(NetworkRunner runner, GameType gameType) {

  var customProps = new Dictionary<string, int>() {
    { "type", (int)gameType }
  };

  await runner.StartGame(new StartGameArgs() {
    GameMode = GameMode.Client,
    SessionProperties = customProps,
  });
}

특정 GameType로 무작위 세션에 클라이언트를 참여하도록 만드는 것이 충분합니다.

메인 화면으로

로비에서 세션 참여

바로 Fusion을 시작하는 대신 로비에서 Sessions를 얻으려면 다른 방법이 필요합니다. 아래의 샘플 코드는 Fusion Runner가 Photon Cloud에 연결하여 미리 정의된 ClientServer 로비에 참여하도록 합니다.

// Utility method to Join the ClientServer Lobby
public async Task JoinLobby(NetworkRunner runner) {

  await runner.JoinSessionLobby(SessionLobby.ClientServer);
}

그리고 앞에서 설명한 것처럼 클라이언트ClientServer, 'Shared', 'Custom' 로비에 참여하는 것이 가능합니다. 서버/호스트가 아래와 같이 Custom 로비에 Session을 생성하는 경우는 아래와 같습니다:

public async Task StartHost(NetworkRunner runner) {

  await runner.StartGame(new StartGameArgs() {
    GameMode = GameMode.Host,
    CustomLobbyName = "MyCustomLobby"
  });
}

클라이언트에서 Lobby 참여 요청은 다음과 같이 변경되어야 합니다:

// Utility method to Join a Custom Lobby
public async Task JoinLobby(NetworkRunner runner) {

  await runner.JoinSessionLobby(SessionLobby.Custom, "MyCustomLobby");
}

연결이 되면 Fusion Runner가 등록된 모든 INetworkRunnerCallbacks에 대해 OnSessionListUpdated콜백을 호출합니다. 아래는 목록에서 첫 번째 세션에 참여하는 방법을 보여주는 예제 코드입니다.

public class MyBehaviour : Fusion.Behaviour, INetworkRunnerCallbacks {

  // other callbacks...

  // Receive the List of Sessions from the current Lobby
  public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList) {

    Debug.Log($"Session List Updated with {sessionList.Count} session(s)");

    foreach (var session in sessionList) {

      Debug.Log($"Joining {session.Name}");

      // This call will make Fusion join the first session as a Client
      runner.StartGame(GameMode.Client, session);
      return;
    }
  }
}


기술문서 TOP으로 돌아가기