For this lesson, we will teach you how to create a code matchmaking system for the Photon Pun 2 plugin in Unity. This system allows players to create a room that will give them a room code. They can then share the code with their friend so their friends can then join the same room. Code matchmaking can be found in a number of popular games like Random Dice. Code matchmaking is a good way to play games with friends if your game does not have friends or party mechanics.
CodeMatchmakingLobbyController.cs
using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.UI; public class CodeMatchmakingLobbyController : MonoBehaviourPunCallbacks { [SerializeField] private GameObject lobbyConnectButton; [SerializeField] private GameObject lobbyPanel; [SerializeField] private GameObject mainPanel; [SerializeField] private InputField playerNameInput; private string roomName; private int roomSize; [SerializeField] private GameObject CreatePanel; [SerializeField] private InputField codeDisplay; [SerializeField] private GameObject joinPanel; [SerializeField] private InputField codeInputField; private string joinCode; [SerializeField] private GameObject joinButton; public override void OnConnectedToMaster() //Callback function for when the first connection is established successfully. { PhotonNetwork.AutomaticallySyncScene = true; //Makes it so whatever scene the master client has loaded is the scene all other clients will load lobbyConnectButton.SetActive(true); //activate button for connecting to lobby //check for player name saved to player prefs if (PlayerPrefs.HasKey("NickName")) { if (PlayerPrefs.GetString("NickName") == "") { PhotonNetwork.NickName = "Player " + Random.Range(0, 1000); //random player name when not set } else { PhotonNetwork.NickName = PlayerPrefs.GetString("NickName"); //get saved player name } } else { PhotonNetwork.NickName = "Player " + Random.Range(0, 1000); //random player name when not set } playerNameInput.text = PhotonNetwork.NickName; //update input field with player name } public void PlayerNameUpdateInputChanged(string nameInput) //input function for player name. paired to player name input field { PhotonNetwork.NickName = nameInput; PlayerPrefs.SetString("NickName", nameInput); } public void JoinLobbyOnClick() //Paired to the Delay Start button { mainPanel.SetActive(false); lobbyPanel.SetActive(true); PhotonNetwork.JoinLobby(); //First tries to join a lobby } public void OnRoomSizeInputChanged(string sizeIn) //input function for changing room size. paired to room size input field { roomSize = int.Parse(sizeIn); } public void CreateRoomOnClick() { CreatePanel.SetActive(true); Debug.Log("Creating room now"); RoomOptions roomOps = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)roomSize }; int roomCode = Random.Range(1000, 10000); roomName = roomCode.ToString(); PhotonNetwork.CreateRoom(roomName, roomOps); //attempting to create a new room codeDisplay.text = roomName; } public override void OnCreateRoomFailed(short returnCode, string message) //create room will fail if room already exists { Debug.Log("Tried to create a new room but failed, there must already be a room with the same name"); RoomOptions roomOps = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)roomSize }; int roomCode = Random.Range(1000, 10000); roomName = roomCode.ToString(); PhotonNetwork.CreateRoom(roomName, roomOps); //attempting to create a new room codeDisplay.text = roomName; } public void CancelRoomOnClick() { if(PhotonNetwork.IsMasterClient) { for(int i = 0; i < PhotonNetwork.PlayerList.Length; i ++) { PhotonNetwork.CloseConnection(PhotonNetwork.PlayerList[i]); } } PhotonNetwork.LeaveRoom(); CreatePanel.SetActive(false); joinButton.SetActive(true); } public void OpenJoinPanel() { joinPanel.SetActive(true); } public void CodeInput(string code) { joinCode = code; } public void JoinRoomOnClick() { PhotonNetwork.JoinRoom(joinCode); } public void LeaveRoomOnClick() { if (PhotonNetwork.InRoom) { PhotonNetwork.LeaveRoom(); } } public override void OnLeftRoom() { joinButton.SetActive(true); joinPanel.SetActive(false); codeInputField.text = ""; } public void MatchmakingCancelOnClick() //Paired to the cancel button. Used to go back to the main menu { mainPanel.SetActive(true); lobbyPanel.SetActive(false); PhotonNetwork.LeaveLobby(); } }
CodeMatchmakingRoomController.cs
using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.UI; public class CodeMatchmakingRoomController : MonoBehaviourPunCallbacks { [SerializeField] private GameObject joinButton; [SerializeField] private Text playerCount; [SerializeField] private Text playerCount2; public override void OnJoinedRoom()//called when the local player joins the room { joinButton.SetActive(false); playerCount.text = PhotonNetwork.PlayerList.Length + " Players" ; playerCount2.text = PhotonNetwork.PlayerList.Length + " Players"; } public override void OnPlayerEnteredRoom(Player newPlayer) //called whenever a new player enter the room { playerCount.text = PhotonNetwork.PlayerList.Length + " Players"; playerCount2.text = PhotonNetwork.PlayerList.Length + " Players"; } public override void OnPlayerLeftRoom(Player otherPlayer) { playerCount.text = PhotonNetwork.PlayerList.Length + " Players"; playerCount2.text = PhotonNetwork.PlayerList.Length + " Players"; } public override void OnLeftRoom() { playerCount.text = "0 Players"; playerCount2.text = "0 Players"; } public override void OnJoinRoomFailed(short returnCode, string message) { Debug.Log(message); } public void StartGameOnClick() { PhotonNetwork.LoadLevel(1); } }
using Photon.Chat; using Photon.Pun; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class PhotonChatManager : MonoBehaviour, IChatClientListener { #region Setup [SerializeField] GameObject joinChatButton; ChatClient chatClient; bool isConnected; [SerializeField] string username; public void UsernameOnValueChange(string valueIn) { username = valueIn; } public void ChatConnectOnClick() { isConnected = true; chatClient = new ChatClient(this); //chatClient.ChatRegion = "US"; chatClient.Connect(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat, PhotonNetwork.AppVersion, new AuthenticationValues(username)); Debug.Log("Connenting"); } #endregion Setup #region General [SerializeField] GameObject chatPanel; string privateReceiver = ""; string currentChat; [SerializeField] InputField chatField; [SerializeField] Text chatDisplay; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (isConnected) { chatClient.Service(); } if (chatField.text != "" && Input.GetKey(KeyCode.Return)) { SubmitPublicChatOnClick(); SubmitPrivateChatOnClick(); } } #endregion General #region PublicChat public void SubmitPublicChatOnClick() { if (privateReceiver == "") { chatClient.PublishMessage("RegionChannel", currentChat); chatField.text = ""; currentChat = ""; } } public void TypeChatOnValueChange(string valueIn) { currentChat = valueIn; } #endregion PublicChat #region PrivateChat public void ReceiverOnValueChange(string valueIn) { privateReceiver = valueIn; } public void SubmitPrivateChatOnClick() { if (privateReceiver != "") { chatClient.SendPrivateMessage(privateReceiver, currentChat); chatField.text = ""; currentChat = ""; } } #endregion PrivateChat #region Callbacks public void DebugReturn(DebugLevel level, string message) { //throw new System.NotImplementedException(); } public void OnChatStateChange(ChatState state) { if(state == ChatState.Uninitialized) { isConnected = false; joinChatButton.SetActive(true); chatPanel.SetActive(false); } } public void OnConnected() { Debug.Log("Connected"); joinChatButton.SetActive(false); chatClient.Subscribe(new string[] { "RegionChannel" }); } public void OnDisconnected() { isConnected = false; joinChatButton.SetActive(true); chatPanel.SetActive(false); } public void OnGetMessages(string channelName, string[] senders, object[] messages) { string msgs = ""; for (int i = 0; i < senders.Length; i++) { msgs = string.Format("{0}: {1}", senders[i], messages[i]); chatDisplay.text += "\n" + msgs; Debug.Log(msgs); } } public void OnPrivateMessage(string sender, object message, string channelName) { string msgs = ""; msgs = string.Format("(Private) {0}: {1}", sender, message); chatDisplay.text += "\n " + msgs; Debug.Log(msgs); } public void OnStatusUpdate(string user, int status, bool gotMessage, object message) { throw new System.NotImplementedException(); } public void OnSubscribed(string[] channels, bool[] results) { chatPanel.SetActive(true); } public void OnUnsubscribed(string[] channels) { throw new System.NotImplementedException(); } public void OnUserSubscribed(string channel, string user) { throw new System.NotImplementedException(); } public void OnUserUnsubscribed(string channel, string user) { throw new System.NotImplementedException(); } #endregion Callbacks }