동작 방식
- 먼저 game_version을 정해준다. 버전이 다른 경우 다르게 동작할 가능성이 있기 때문이다.
- 이후 변경한 설정을 바탕으로 Master Server와의 연결을 시도한다.
- 만일 연결에 성공했다면 다음 단계로 넘어가고, 연결에 실패했다면 연결에 성공할 때까지 계속해서 ConnectUsingSettings()를 호출한다. (여기서 더 나아가서 만일 연결을 시도한지 1분이 넘었다면 개인전 화면으로 넘어가게 만들 수도 있다!)
- 이제 join button을 눌렀는가?를 동작 기준으로 삼는다.
- Master Server와 연결이 되어있는 상태에서 join button을 눌렀다면 RandomRoom에 Join한다.
- Master Server와 연결이 되어있지 않은 상태에서 join button을 눌렀다면 다시 ConnectUsingSettings()를 호출한다. (참고로 join button을 누를 수 있다는 사실 자체가 Master Server와 연결이 되었다는 것을 보장하긴 하지만, 혹시 몰라서 넣어둔 것이다!)
- Room Joining에 성공했다면 Scene을 전환한다. 여기서 Main Scene은 게임이 이루어지는 Scene이라고 생각하면 된다.
- 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를 해야 한다.
읽어주셔서 감사합니다!