반응형
이전 글에서 포스팅한 RaiseEvent를 사용했으며 원리는 매우 비슷하다
이전 글 : https://red-tiger.tistory.com/69
우선 방에 입장하거나 방을 만들었을 때 띄울 UI를 적당히 만들어준다
우선 방에 들어왔을때 중앙의 버튼의 텍스트가 본인이 마스터 클라이언트인지 아닌지에 따라 달라지게 구현한다.
마스터 클라이언트일 때
마스터 클라이언트가 아닐 때
그리고 만약 중앙에 버튼을 눌렀을때 마스터 클라이언트인지 아닌지에 따라 코드가 다르게 실행되게한다.
이 게임은 4명이 들어와야 플레이 할 수 있게 만들었다
count는 현재 방에 들어와있는 사람의 숫자다.
나머지 코드는 이전 포스팅의 RaiseEvent와 매우매우 비슷하다
내 전체코드에서 #region RaiseEvent 부분을 살펴보면 된다
마지막으로 마스터클라이언트가 게임을 시작해서 플레이화면으로 넘어가면 다른 클라이언트들도 플레이화면으로 넘어가야 하므로 Awake() 부분에
위와 같이 PhotonNetwork.AutomaticallySyncScene=true를 넣어준다
LobbyManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Photon.Pun;
using Photon.Realtime;
using ExitGames.Client.Photon;
public class LobbyManager : MonoBehaviourPunCallbacks//for using PUN2 Network callback
{
[Header("---UI Screens---")]
public GameObject roomUI;
public GameObject connectUI;
public GameObject lobbyUI;//로비 UI통째로
[Header("---UI Text---")]
public TMP_Text statusText;
public TMP_Text connectingText;
public Text startBtnText;
public Text lobbyText;
[Header("---UI InputFields---")]
public TMP_InputField createRoom;
public TMP_InputField joinRoom;
public Button startButton;
public TMP_InputField userName;
private void Awake()
{
PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.AutomaticallySyncScene=true;// 방장이 플레이 씬으로 넘어가면 다른 클라이언트도 넘어가게
}//Connect to PhotonNetwork based on UsingSetting
//You can check your UsingSetting on your asset folder
public override void OnConnectedToMaster()
{
connectingText.text="Joining Lobby...";
PhotonNetwork.JoinLobby(TypedLobby.Default);
}// Called when the client is connected to the Master Server and ready for matchmaking and other tasks.
public override void OnJoinedLobby()
{
connectUI.SetActive(false);
roomUI.SetActive(true);
statusText.text="Joined To Lobby...";
userName.text="Player" + Random.Range(100,999);
}// Called on entering a lobby on the Master Server. The actual room-list updates will call OnRoomListUpdate.
public override void OnJoinedRoom()
{
int sizeOfPlayers=PhotonNetwork.CurrentRoom.PlayerCount;
AssignTeam(sizeOfPlayers);
lobbyUI.SetActive(true);//로비 UI를 켜준다
if(PhotonNetwork.IsMasterClient)//만약 내가 마스터 클라이언트라면
{
startBtnText.text="waiting for players";
}
else
{
startBtnText.text="Ready!";
}
//Loading the index 1 scene
}
public override void OnDisconnected(DisconnectCause cause)
{
connectUI.SetActive(true);
roomUI.SetActive(false);
connectingText.text="Disconnected..."+cause.ToString();
}//If fail to connect...
public override void OnJoinRandomFailed(short returnCode, string message)
{
int roomName=Random.Range(0,10000);
RoomOptions roomOptions = new RoomOptions();
roomOptions.MaxPlayers=4;
PhotonNetwork.CreateRoom(roomName.ToString(),roomOptions,TypedLobby.Default,null);//take above room options
}//If this function is executed because of failure of Onclick_PlayNow()
//Creating room with random number and join it.
#region ButtonClicks
public void OnClick_CreateBtn()
{
RoomOptions roomOptions = new RoomOptions();
roomOptions.MaxPlayers=4;
PhotonNetwork.CreateRoom(createRoom.text,roomOptions,TypedLobby.Default,null);//take above room options
}
public void OnClick_JoinBtn()
{
PhotonNetwork.JoinRoom(joinRoom.text,null);
}
public void OnClick_PlayNow()
{
if(string.IsNullOrEmpty(userName.text))//유저네임이 비어있다면
{
userName.text="Uses" + Random.Range(100,999);
}
PhotonNetwork.LocalPlayer.NickName = userName.text;
//로컬플레이어의 닉네임설정
PhotonNetwork.JoinRandomRoom();
statusText.text="Creating Room...Please Wait...";
//Joining Random room if it is available
//if it is not available and failed to connect, OnJoinRandomFailed function will be executed
}//function for Button PlayNow
#endregion
#region My_Functions
void AssignTeam(int sizeOfPlayer)
{
ExitGames.Client.Photon.Hashtable hash=new ExitGames.Client.Photon.Hashtable();
if(sizeOfPlayer%2==0)
{
hash.Add("Team",0);
}
else
{
hash.Add("Team",1);
}
PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
}
#endregion
public void OnClickStartButton()
{
if(!PhotonNetwork.IsMasterClient)//방장이 아닌 참가자라면
{
SendMsg();
startButton.interactable=false;//한번 레디 누르면 못 바꾼다
startBtnText.text="Wait...";
}
else
{
if(count==4)//모든 플레이어가(4명) 준비 완료되었다면
{
lobbyText.text="All Set : Play the Game Scene";
PhotonNetwork.LoadLevel(1);//1번째 씬을 불러온다
}
}
}
#region RasieEvent
private void OnEnable()
{
base.OnEnable();
PhotonNetwork.NetworkingClient.EventReceived+=OnEvent;
}
private void OnDisable()
{
PhotonNetwork.NetworkingClient.EventReceived-=OnEvent;
}
enum EventCodes
{
ready=1
}
int count =1;
public void OnEvent(EventData photonEvent)
{
byte eventCode = photonEvent.Code;
object content=photonEvent.CustomData;
EventCodes code=(EventCodes)eventCode;
if(code==EventCodes.ready)//받은 이벤트의 분류가 ready라면
{
object[] datas=content as object[];
if(PhotonNetwork.IsMasterClient)//내가 마스터클라이언트라면
{
count++;
if(count==4)//모두 준비완료가 되었다면
{
startBtnText.text="START !";
}
else
{
startBtnText.text="Only "+ count + " / 4 players are Ready";
}
}
}
}
private void SendMsg()
{
string message = PhotonNetwork.LocalPlayer.ActorNumber.ToString();
object[] datas=new object[] { message };
RaiseEventOptions options = new RaiseEventOptions
{
CachingOption = EventCaching.DoNotCache,
Receivers = ReceiverGroup.MasterClient,//마스터 클라이언트(방장)에게만 보낸다
};
SendOptions sendOp=new SendOptions();
sendOp.Reliability=true;
PhotonNetwork.RaiseEvent((byte)EventCodes.ready,datas,options,sendOp);
}
#endregion
}
실행영상
반응형
'유니티 > 모바일 멀티플레이 Shooting Game' 카테고리의 다른 글
Udemy 유니티 모바일 멀티플레이 TPS 슈팅게임 강의 리뷰 (1) | 2023.05.16 |
---|---|
유니티 Photon의 RaiseEvents를 이용한 채팅 시스템 (0) | 2023.03.16 |
유니티 3D 멀티플레이 RPC이용법(플레이어 체력 깎기) (0) | 2023.02.24 |
유니티3D OnPhotonSerializeView() 사용법 (0) | 2023.02.05 |
유니티 Photon으로 간단하게 핑 확인법 (0) | 2023.01.28 |