내일배움캠프 46일차 6/20 TIL + Photon 서버 적용
포톤 서버 적용 (Pun2)
이번 팀 프로젝트는 혈압 마라톤 모작의 멀티게임을 구현하는 것이었습니다. 제가 맡은 부분은 플레이어 간의 네트워크 통신으로, Photon 서버를 이용해 Pun2를 사용하여 제작했습니다.
Photon 서버의 Pun은 P2P 방식으로, 서버는 플레이어를 룸까지 매칭만 시켜주고, 그 이후로는 룸의 첫 생성자인 마스터와 나머지 클라이언트로 이루어진 네트워크 방식입니다.
1. 연결 설정
룸에 연결하는 메서드
public void ConnectToRoom()
{
if (PhotonNetwork.IsConnected)
{
// 랜덤한 룸에 연결
if (isConnecting)
{
PhotonNetwork.JoinRandomRoom();
}
}
else
{
// 현재 포톤 연결 세팅에 맞춰서 연결
PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.GameVersion = gameVersion;
}
}
위 메서드는 룸에 빠르게 연결하는 방법입니다. 비슷한 방식으로, 연결되어 있으면 룸이나 로비로 들어가게 됩니다.
2. 룸 및 로비 관리
룸 리스트 업데이트
룸 리스트를 화면에 표시하기 위한 코드입니다:
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
base.OnRoomListUpdate(roomList);
foreach (RoomInfo roomInfo in roomList)
{
if (roomDict.ContainsKey(roomInfo.Name))
{
Destroy(roomDict[roomInfo.Name]);
roomDict.Remove(roomInfo.Name);
}
else
{
if (!roomDict.ContainsKey(roomInfo.Name))
{
GameObject roomEntry = Instantiate(roomListPrefab, roomListParent);
roomEntry.GetComponentInChildren<TextMeshProUGUI>().text = $"방 이름 : {roomInfo.Name.Substring(0, 4)}\n현재 인원 : {roomInfo.PlayerCount}";
Button button = roomEntry.GetComponent<Button>();
button.onClick.AddListener(() =>
{
JoinRoom(roomInfo.Name);
});
roomDict.Add(roomInfo.Name, roomEntry);
}
}
}
}
Photon은 룸 목록 업데이트 기능을 자체적으로 제공하여 매우 편리했습니다.
3. 룸 참여 및 플레이어 목록
플레이어 목록 표시 및 게임 시작
룸에 참여하면 플레이어 목록을 보여주고, 인원이 최대치가 되면 게임을 자동으로 시작합니다:
[PunRPC]
private void MakePlayerListContent(int id)
{
GameObject newListContent = Instantiate(playerListContentPrefab, playerListParent);
TextMeshProUGUI tmp = newListContent.GetComponentInChildren<TextMeshProUGUI>();
tmp.SetText($"유저 Id : {id}");
if (PhotonNetwork.IsMasterClient)
{
playerObjectList.add(id, newListContent);
}
}
RPC를 사용하면 특정 메서드를 한 명이 실행할 때 나머지 모두가 함께 실행됩니다:
photonView.RPC("MakePlayerListContent", RpcTarget.AllBuffered, playerInGameId);
게임이 시작되기 전, 최대 인원이 모두 찼을 때 10초 카운트 다운을 하며, 도중에 플레이어가 나가면 게임 시작을 취소하고 해당 플레이어를 목록에서 제외합니다:
public override void OnPlayerLeftRoom(Photon.Realtime.Player otherPlayer)
{
if (!PhotonNetwork.IsMasterClient) { return; }
base.OnPlayerLeftRoom(otherPlayer);
RemovePlayerFromData(otherPlayer);
}
Photon은 다양한 콜백 메서드를 제공하여 이런 특수 상황에 편리하게 대응할 수 있었습니다.
이제 뒤에는 플레이어와 같은 네트워크 데이터에서 정보가 필요한 객체의 생성, 각 개인의 조작으로 변화한 내용의 동기화가 남았습니다.