본문 바로가기

유니티/모바일 멀티플레이 Shooting Game

유니티 RaiseEvent를 이용한 준비 완료 시스템

반응형

이전 글에서 포스팅한 RaiseEvent를 사용했으며 원리는 매우 비슷하다

 

이전 글 : https://red-tiger.tistory.com/69

 

유니티 Photon의 RaiseEvents를 이용한 채팅 시스템

UI에 관한 건 스킵하겠다. 각자 본인 마다 원하는 UI 배치가 있을꺼니깐. 나는 이 포스팅에선 모바일 전용이니깐 키보드로 입력하는 것이 아닌 미리 정해진 구문을 누르면 메세지를 보낼 수 있게

red-tiger.tistory.com

 

 

우선 방에 입장하거나 방을 만들었을 때 띄울 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

}

 

 

실행영상

 

 

 

반응형