동작 방식

  1. 먼저 game_version을 정해준다. 버전이 다른 경우 다르게 동작할 가능성이 있기 때문이다.
  2. 이후 변경한 설정을 바탕으로 Master Server와의 연결을 시도한다.
  3. 만일 연결에 성공했다면 다음 단계로 넘어가고, 연결에 실패했다면 연결에 성공할 때까지 계속해서 ConnectUsingSettings()를 호출한다. (여기서 더 나아가서 만일 연결을 시도한지 1분이 넘었다면 개인전 화면으로 넘어가게 만들 수도 있다!)
  4. 이제 join button을 눌렀는가?를 동작 기준으로 삼는다.
  5. Master Server와 연결이 되어있는 상태에서 join button을 눌렀다면 RandomRoom에 Join한다. 
  6. Master Server와 연결이 되어있지 않은 상태에서 join button을 눌렀다면 다시 ConnectUsingSettings()를 호출한다. (참고로 join button을 누를 수 있다는 사실 자체가 Master Server와 연결이 되었다는 것을 보장하긴 하지만, 혹시 몰라서 넣어둔 것이다!)
  7. Room Joining에 성공했다면 Scene을 전환한다. 여기서 Main Scene은 게임이 이루어지는 Scene이라고 생각하면 된다. 
  8. Room Joining에 실패했다면 3인용 Room을 따로 판다. 호스트는 룸을 새로 생성한 클라이언트에게 할당된다.

Lobby Manager 코드

using Photon.Pun; // 고수준 API (90%의 Unity 게임은 이것만 사용해도 상관없음)
using Photon.Realtime; // 저수준 API (세밀한 조작이 필요한 경우 사용)
using UnityEngine;
using UnityEngine.UI;

public class LobbyManager : MonoBehaviourPunCallbacks
{
    [SerializeField] private string game_version;

    [SerializeField] private Text info_text;
    [SerializeField] private Button join_button;

    private void Awake()
    {
        DoInitialSettings();
    }

    private void DoInitialSettings()
    {
        PhotonNetwork.GameVersion = game_version;
    }

    private void Start() 
    {
        TryJoiningMasterServer();
    }

    // try joining the master server
    private void TryJoiningMasterServer()
    {
        PhotonNetwork.ConnectUsingSettings(); // use the settings(for now, it's game_version) to connect to the master server
        join_button.interactable = false;
        info_text.text = "trying to join the master server...";
    }

    // automatically called when the connection to master server succeeds
    public override void OnConnectedToMaster()
    {
        join_button.interactable = true;
        info_text.text = "connected (master server)";
    }

    // automatically called when the connection to master server fails
    public override void OnDisconnected(DisconnectCause cause)
    {
        join_button.interactable = false;
        info_text.text = "failed to connect (master server)\nretrying to connect...";
        PhotonNetwork.ConnectUsingSettings();
    }

    // when pressing the join button (UI)
    public void Connect() 
    {
        join_button.interactable = false;

        if (PhotonNetwork.IsConnected) // if connected to the master server (true)
        {
            info_text.text = "joining room...";
            PhotonNetwork.JoinRandomRoom(); // if success, OnJoinedRoom() || if fails, OnJoinRandomFailed()
        }
        else // if NOT connected to the master server (false)
        {
            info_text.text = "not connected to the master server!\nretrying to connect...";
            PhotonNetwork.ConnectUsingSettings();
        }
    }

    // when there's no VACANT room
    public override void OnJoinRandomFailed(short returnCode, string message) 
    {
        info_text.text = "no vacant room exists.\ncreating a new room...";
        PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = 3 }); // 룸은 리슨 서버 방식으로 동작함. 룸을 생성한 클라이언트가 호스트로 선정됨.
    }

    // when succeeded to join the room
    public override void OnJoinedRoom() 
    {
        info_text.text = "joined the room!";
        PhotonNetwork.LoadLevel("Main"); // LoadLevel != SceneManager.LoadScene("~~~"); 거의 비슷하지만 Photon 쪽이 동기화를 제공함.
    }
}

참고사항

  • LobbyManager Script는 Monobehaviour 대신 MonoBehaviourPunCallbacks를 상속한다. OnConnectedToMaster와 같은 커스텀 이벤트를 받기 위함이다. 
  • MonoBehaviourPunCallbacks에 있는 커스텀 이벤트를 사용하기 위해선 꼭 override를 해야 한다. 

읽어주셔서 감사합니다!

+ Recent posts