How to connect to your friend room in pun 2?
Hi guys I am using pun 2 as you can tell from the title and I want to ask how can I join to my friend party?
I have a list of my friends but I do not know how to do it pls help I am stuck on it a lot of time. I know there is a thing that called expected players and I check the Matchmaking Guide. didn't understand it ):
I have a list of my friends but I do not know how to do it pls help I am stuck on it a lot of time. I know there is a thing that called expected players and I check the Matchmaking Guide. didn't understand it ):
1
Comments
-
pls help
1 -
I working on party system also and basic functions already completed, what I did was using Photon Chat channel for making party with friends(You need to write your own custom chat message to determine message type like example party invite, party accept, party left and etc) and record down the players ID then put into expected players field when doing match making0
-
Hi @TeohTC Can you send your code for this, I want to look. thx
Don't expect it to work out of box...I have remove tons of unrelated code, but concept of party system is there
Chat Managerusing System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using Photon.Chat; using Photon.Realtime; using Photon.Pun; using ExitGames.Client.Photon; public class ChatManagerScript : MonoBehaviour, IChatClientListener{ public enum ChatRegion { EU, US, ASIA } //Enum for message type public enum MessageType {PublicMessage, PrivateMessage, PartyInvite, PartyInviteWithPartyID, Party_AlreadyInParty, PartyAccept, PartyReject, PartyLeft, Party_MatchMaking, Party_MatchMaking_Cancel} //Singleton public static ChatManagerScript instance; //Photon Chat ChatClient chatClient; protected internal AppSettings chatAppSettings; private ChatRegion currentChatRegion; public ChatState chatState; bool chatConnected = false; [Header("Public Channel Configuration")] [SerializeField] private string[] publicChatChannel = new string[]{"Global"}; //Party UnityEvent party_SuccessCallback, party_FailCallback; private string party_ChannelName; private void Awake() { instance = this; } /// <summary>To avoid that the Editor becomes unresponsive, disconnect all Photon connections in OnApplicationQuit.</summary> public void OnApplicationQuit() { if (this.chatClient != null) { this.chatClient.Disconnect(); } } // Update is called once per frame void Update(){ if (this.chatClient != null) { this.chatClient.Service(); // make sure to call this regularly! it limits effort internally, so calling often is ok! } } /// <summary> /// To initialize the chat region /// </summary> /// <param name="chatRegion"></param> public void InitializePhotonChat(ChatRegion chatRegion){ if(chatConnected) return; //Set chat app setting chatAppSettings = PhotonNetwork.PhotonServerSettings.AppSettings; currentChatRegion = chatRegion; // In the C# SDKs, the callbacks are defined in the `IChatClientListener` interface. // In the demos, we instantiate and use the ChatClient class to implement the IChatClientListener interface. chatClient = new ChatClient(this); // Set your favourite region. "EU", "US", and "ASIA" are currently supported. chatClient.ChatRegion = chatRegion.ToString(); var authValues = new Photon.Chat.AuthenticationValues(); authValues.AuthType = Photon.Chat.CustomAuthenticationType.Custom; authValues.UserId = PhotonNetwork.LocalPlayer.UserId; chatClient.Connect(chatAppSettings.AppIdChat, Application.version, authValues); } /// <summary> /// To initialize the chat region /// </summary> /// <param name="chatRegion"></param> public void InitializePhotonChat(ref string photonConnectedRegion){ if(chatConnected) return; currentChatRegion = GetChatRegion(ref photonConnectedRegion); InitializePhotonChat(currentChatRegion); } public void PhotonChat_Reconnect(){ InitializePhotonChat(currentChatRegion); } /// <summary> /// Switch the chat region if needed /// </summary> /// <param name="chatRegion"></param> void SwitchRegion(ChatRegion chatRegion) { if(currentChatRegion == chatRegion) return; if (this.chatClient != null) { this.chatClient.Disconnect(); } InitializePhotonChat(chatRegion); } #region Public Chat Channel /// <summary> /// To subscribe to public channel /// </summary> public void PublicChatChannel_Subscribe(){ if(chatClient == null || chatConnected == false){ StartCoroutine(PublicChatChannel_AttemptToConnect()); }else{ chatClient.Subscribe(publicChatChannel); } } /// <summary> /// To Unsubscribe the public channel /// </summary> public void PublicChatChannel_Unsubscribe(){ chatClient.Unsubscribe(publicChatChannel); } IEnumerator PublicChatChannel_AttemptToConnect(){ //If is null then pause till not null while(chatClient == null){ yield return new WaitForFixedUpdate(); } while(!chatConnected){ yield return new WaitForFixedUpdate(); } chatClient.Subscribe(publicChatChannel); } /// <summary> /// To send message to public channel /// </summary> /// <param name="message"></param> /// <param name="chatChannel"></param> public void PublicChatChannel_Send(ref string message){ //Repackage the message MessageContainer mc; mc.senderUserIGN = PlayersDataScript.instance.playerProfile.player_IGN; mc.messageType = MessageType.PublicMessage; mc.message = message; mc.data = ""; chatClient.PublishMessage(publicChatChannel[0], mc); } /// <summary> /// Send message to target channel /// </summary> /// <param name="channel"></param> /// <param name="message"></param> public void PublicChatChannel_Send(ref string channel, ref MessageContainer message){ chatClient.PublishMessage(channel, message); } /// <summary> /// To handle the received message /// </summary> /// <param name="channel"></param> /// <param name="ign"></param> /// <param name="message"></param> void PublicChatChannel_Receive(MessageContainer message){ //Ask Chat System to spawn MainMenuChatManagerScript.instance.Chat_ReceiveMessage(ref message.senderUserIGN, ref message.message); } #endregion #region Friend Chat /// <summary> /// Function to send out the message /// </summary> /// <param name="uid"></param> /// <param name="messageContainer"></param> public void FriendChat_Send(string uid, MessageContainer messageContainer){ chatClient.SendPrivateMessage(uid, messageContainer); } /// <summary> /// Function to interpret the message /// </summary> /// <param name="uid"></param> /// <param name="messageData"></param> void FriendChat_ReceiveMessage(ref string sender, ref string channel, object messageData){ MessageContainer message = (MessageContainer)messageData; //Debug.Log("Message Type: " + message.messageType.ToString() + ", Message: " + message.senderUserID + message.message + ", Data: " + message.data); switch(message.messageType){ case MessageType.PartyInvite: case MessageType.PartyInviteWithPartyID: PartySystemScript.instance.Party_Invite(ref sender, message); break; case MessageType.PartyAccept: PartySystemScript.instance.Party_Inviter_PlayerAccept(ref sender, ref message.senderUserIGN); break; case MessageType.Party_AlreadyInParty: PartySystemScript.instance.Party_Inviter_Error_PlayerAlreadyInParty(ref message.senderUserIGN); break; } } #endregion #region Party public void Party_JoinParty(ref string channelName, UnityEvent successCallback, UnityEvent failCallback){ party_SuccessCallback = successCallback; party_FailCallback = failCallback; party_ChannelName = channelName; ChannelCreationOptions cco = new ChannelCreationOptions(); cco.PublishSubscribers = true; cco.MaxSubscribers = 3; chatClient.Subscribe(channelName, 0, -1, new ChannelCreationOptions(){PublishSubscribers = true, MaxSubscribers = 3}); } void Party_SuccessCreated(){ party_SuccessCallback?.Invoke(); } void Party_FailToCreate(){ party_FailCallback?.Invoke(); } void Party_PartyTeamUpdate(bool isUnsubscribe, ref string userName){ Photon.Chat.ChatChannel cc; if(chatClient.TryGetChannel(party_ChannelName, out cc)){ int count = cc.Subscribers.Count; HashSet<string> subscribers = cc.Subscribers; PartySystemScript.instance.Party_UpdateInPartyCount(count, isUnsubscribe, ref subscribers, ref userName); } } /// <summary> /// To unsubscribe from the party chat channel /// </summary> public void Party_LeftParty(ref string userID){ //Unsubscribe from the channel party chatClient.Unsubscribe(new string[]{party_ChannelName}); } /// <summary> /// Function to interpret the received message /// </summary> /// <param name="message"></param> public void Party_ReceiveMessage(ref string sender, object message){ MessageContainer mc = (MessageContainer)message; //Pass to party system to handle the message PartySystemScript.instance.Party_ReceiveMessage(ref sender, ref mc); } #endregion #region Helper ChatRegion GetChatRegion(ref string currentConenctedRegion){ ChatRegion region = ChatRegion.ASIA; switch(currentConenctedRegion){ case "asia": case "au": case "in": case "jp": case "rue": case "kr": region = ChatRegion.ASIA; break; case "eu": case "ru": region = ChatRegion.EU; break; case "us": case "cae": case "sa": case "usw": region = ChatRegion.US; break; } return region; } /// <summary> /// To get the channel name /// </summary> /// <param name="channelName"></param> /// <param name="channel"></param> /// <returns></returns> public bool GetChannel(ref string channelName, out Photon.Chat.ChatChannel channel){ if(chatClient != null){ return chatClient.TryGetChannel(channelName, false, out channel); }else{ channel = null; return false; } } public bool Chat_IsConnected(){ if(chatClient == null) return false; if(chatClient.State == ChatState.ConnectedToFrontEnd) return true; else return false; } #endregion #region Photon Chat Callback Function public void DebugReturn(DebugLevel level, string message) { if (level == ExitGames.Client.Photon.DebugLevel.ERROR) { Debug.LogError(message); } else if (level == ExitGames.Client.Photon.DebugLevel.WARNING) { Debug.LogWarning(message); } else { Debug.Log(message); } } public void OnDisconnected() { Debug.Log("Photon Chat: Disconnect, attempt to reconnect"); chatConnected = false; PhotonChat_Reconnect(); } public void OnConnected() { chatConnected = true; Debug.Log("Photon Chat: Connected"); } public void OnChatStateChange(ChatState state) { chatState = state; } public void OnGetMessages(string channelName, string[] senders, object[] messages) { int loopCount = senders.Length; if(channelName == ConstStringContainer.chat_PublicChannel){ //Spawn the message for(int i = 0; i < loopCount; i++){ //Convert the object to message MessageContainer mc = (MessageContainer)messages[i]; PublicChatChannel_Receive(mc); } }else if(channelName == party_ChannelName){ //Party chat for(int i = 0; i < loopCount; i++){ Party_ReceiveMessage(ref senders[i], messages[i]); } } } public void OnPrivateMessage(string sender, object message, string channelName) { FriendChat_ReceiveMessage(ref sender, ref channelName, message); } public void OnSubscribed(string[] channels, bool[] results) { int loopCount = channels.Length; for(int i = 0; i < loopCount; i++){ if(results[i]){ Debug.Log("Chat: Success subscribe to channel " + channels[i]); if(channels[i].Equals(party_ChannelName)){ Party_SuccessCreated(); } }else{ Debug.Log("Chat: Fail subscribe to channel " + channels[i]); if(channels[i].Equals(party_ChannelName)){ Party_FailToCreate(); } } } } public void OnUnsubscribed(string[] channels) { int loopCount = channels.Length; for(int i = 0; i < loopCount; i++){ Debug.Log("Chat: unsubscribe to channel " + channels[i]); } } public void OnStatusUpdate(string user, int status, bool gotMessage, object message) { throw new System.NotImplementedException(); } public void OnUserSubscribed(string channel, string user) { //Check for party if(channel.Equals(party_ChannelName)){ Party_PartyTeamUpdate(false, ref user); } } public void OnUserUnsubscribed(string channel, string user) { Debug.Log("Chat: User Unsubscribed " + user); //Check for party if(channel.Equals(party_ChannelName)){ Party_PartyTeamUpdate(true, ref user); } } #endregion } public struct MessageContainer{ public ChatManagerScript.MessageType messageType; //To know which message type public string senderUserIGN; public string message; public string data; }
Party System Managerusing UnityEngine; using UnityEngine.Events; using Lean.Localization; using Photon.Pun; using Photon.Chat; using System; using System.Collections; using System.Collections.Generic; using System.Linq; public class PartySystemScript : MonoBehaviour{ //Singleton public static PartySystemScript instance; //Instance ChatManagerScript chatManager; MainMenuScript mainMenuScript; PartySystemUIScript partySystemUIScript; private bool party_InParty = false; public bool party_Inparty { get { return party_InParty; } } //Caching private string senderIGN, senderUID; //Handle created party private string party_PartyName = ""; private int party_TotalPlayer = 0; public int party_PlayerCount { get { return party_TotalPlayer; } } private bool party_Leader = false; public bool party_IsLeader { get { return party_Leader; } } private string party_Leader_UserID = ""; private HashSet<string> party_List_PlayerList = new HashSet<string>(); //This list to store player ID list [Header("Join Party")] [SerializeField] private UnityEvent joinParty_Success_Event; [SerializeField] private UnityEvent joinParty_Fail_Event; IEnumerator Start() { chatManager = ChatManagerScript.instance; mainMenuScript = MainMenuScript.instance; partySystemUIScript = PartySystemUIScript.instance; joinParty_Success_Event.AddListener(JoinParty_Success); joinParty_Fail_Event.AddListener(JoinParty_Fail); yield return new WaitForSeconds(0.5f); InParty_GetInPartyStatus(); //Initialize } void OnEnable() { instance = this; } void OnDisable() { instance = null; } private void OnApplicationQuit() { Party_SetInParty(false); } #region Invite Receiver /// <summary> /// To prompt user about party invite /// </summary> public void Party_Invite(ref string senderUserID, MessageContainer messageData){ //If same sender name then dont know if(PhotonNetwork.LocalPlayer.UserId.Equals(senderUserID)) return; //If already in party then dont show and reply to sender that this client in party if(party_InParty){ Party_Invitee_ReplyAlreadyInParty(ref senderUserID); return; } //Generate message string message = senderIGN + (string)LeanLocalization.GetTranslation(ConstStringContainer.localize_Transl_Party_InviteMessage).Data; //Show the party board MainMenuNoticeScript.instance.Party_Invite_ShowInvite(ref message); //Cache this.senderIGN = messageData.senderUserIGN; //The userID actually storing the IGN senderUID = senderUserID; party_Leader_UserID = messageData.message; //Only store then party name is not null if(messageData.data.Equals("")){ party_PartyName = messageData.data; } } /// <summary> /// To accept the party invite /// </summary> public void Party_Invitee_Accept(){ MessageContainer messageContainer; messageContainer.senderUserIGN = PlayersDataScript.instance.playerProfile.player_IGN; messageContainer.messageType = ChatManagerScript.MessageType.PartyAccept; messageContainer.data = ""; messageContainer.message = ""; //Replay client with accept chatManager.FriendChat_Send(senderUID, messageContainer); //Create a party name which will be use for chat channel also if(party_PartyName.Equals("")) party_PartyName = senderUID + "_Party"; //Set in party Party_SetInParty(true, ref party_PartyName); Party_SetPartyLeader(false); //join chat channel as party chatManager.Party_JoinParty(ref party_PartyName, joinParty_Success_Event, joinParty_Fail_Event); } /// <summary> /// To reject the party invite /// </summary> public void Party_Invitee_Reject(){ party_PartyName = ""; //Set in party Party_SetInParty(false, ref party_PartyName); party_Leader_UserID = ""; } /// <summary> /// This function will reply the inviter that this player already in someone party /// </summary> void Party_Invitee_ReplyAlreadyInParty(ref string targetMessageReceiver){ MessageContainer mc; mc.messageType = ChatManagerScript.MessageType.Party_AlreadyInParty; mc.data = ""; mc.message = ""; mc.senderUserIGN = PlayersDataScript.instance.playerProfile.player_IGN; chatManager.FriendChat_Send(targetMessageReceiver, mc); } #endregion #region Invite Sender /// <summary> /// Function to send invite to the player /// </summary> /// <param name="userID">Target Receiver</param> public void Party_Inviter_InvitePlayer(ref string userID){ MessageContainer messageContainer; if(!party_InParty){ messageContainer.senderUserIGN = PlayersDataScript.instance.playerProfile.player_IGN; messageContainer.messageType = ChatManagerScript.MessageType.PartyInvite; messageContainer.message = PhotonNetwork.LocalPlayer.UserId; //This use to store the party host ID messageContainer.data = "Room ID"; //Might need to replace this }else{ //Check is party full before send invite if(InParty_IsPartyFull()){ string message = (string)Lean.Localization.LeanLocalization.GetTranslation(ConstStringContainer.localize_Transl_Party_PartyFull).Data; //Show party full error MainMenuNoticeScript.instance.ErrorNotice_Show(ref message); return; } messageContainer.senderUserIGN = PlayersDataScript.instance.playerProfile.player_IGN; messageContainer.messageType = ChatManagerScript.MessageType.PartyInviteWithPartyID; messageContainer.message = party_Leader_UserID; //Include the host ID messageContainer.data = party_PartyName; //Might need to replace this } chatManager.FriendChat_Send(userID, messageContainer); } /// <summary> /// This function call when target player accept party invite /// </summary> public void Party_Inviter_PlayerAccept(ref string playerName, ref string playerID){ if(party_InParty == false){ //Create a party name which will be use for chat channel also party_PartyName = PhotonNetwork.LocalPlayer.UserId + "_Party"; //Set in party Party_SetInParty(true, ref party_PartyName); //join chat channel as party chatManager.Party_JoinParty(ref party_PartyName, joinParty_Success_Event, joinParty_Fail_Event); Party_SetPartyLeader(true); } } /// <summary> /// Interpret message received from chat manager /// To handle the invited player already in party /// </summary> /// <param name="playerName"></param> public void Party_Inviter_Error_PlayerAlreadyInParty(ref string playerName){ MainMenuNoticeScript.instance.ErrorNotice_Show((string)LeanLocalization.GetTranslation(ConstStringContainer.localize_Transl_Party_AlreadyInParty).Data); } #endregion #region Join Party void JoinParty_Success(){ partySystemUIScript.InParty_Dialogue_Show(true); //Hide the game start button or set it to not clickable if(party_Leader == false) mainMenuScript.GameMode_Buttons_SetActive(false); } void JoinParty_Fail(){ partySystemUIScript.InParty_Dialogue_Show(false); mainMenuScript.GameMode_Buttons_SetActive(true); } #endregion #region In party /// <summary> /// Initialzie function /// To check whether player is in party for situation when player return from gameplay /// </summary> void InParty_GetInPartyStatus(){ //If chat haven't initialize then dont do the check if(ChatManagerScript.instance.Chat_IsConnected() == false){ Party_SetInParty(false); return; } party_InParty = (PlayerPrefs.GetInt(ConstStringContainer.party_InParty_Key, 0) == 0)? false: true; party_PartyName = PlayerPrefs.GetString(ConstStringContainer.party_PartyName_Key); //Check whether in the channel, if in channel mean in party if(party_InParty){ ChatChannel chatChannel; //True then the channel was found, mean player in party if(chatManager.GetChannel(ref party_PartyName, out chatChannel)){ //Set is party leader party_Leader = (PlayerPrefs.GetInt(ConstStringContainer.Party_PartyLeader_Key) == 0)? false : true; //Initialize UI party system related function JoinParty_Success(); }else{ //Else then reset the inparty status party_PartyName = ""; Party_SetInParty(false, ref party_PartyName); } } } /// <summary> /// In Party Function /// To quit the party /// </summary> public void InParty_LeftParty(){ //Unsubscribe from the party chat channel string userID = PhotonNetwork.LocalPlayer.UserId; chatManager.Party_LeftParty(ref userID); //Hide In Party UI partySystemUIScript.InParty_Dialogue_Show(false); //Enable the start game related button mainMenuScript.GameMode_Buttons_SetActive(true); //Reset the cache Party_ClearCache(); //Set in party Party_SetInParty(false, ref party_PartyName); } public bool InParty_IsPartyFull(){ ChatChannel cc; chatManager.GetChannel(ref party_PartyName, out cc); if(cc.MaxSubscribers == party_TotalPlayer){ return true; }else{ return false; } } public void InParty_GetPartyLeaderUserID(out string cacheString){ cacheString = party_Leader_UserID; } /// <summary> /// To get the others player ID without the party leader /// </summary> /// <param name="targetList"></param> public void InParty_GetOthersPlayer(out HashSet<string> targetList){ targetList = party_List_PlayerList; targetList.Remove(party_Leader_UserID); } /// <summary> /// Check is player in party, if in party then call to switch the panel /// </summary> public void InParty_SwitchToCharacterSelectionCheck(int modeNo, ref string map){ if(party_InParty){ //Send Message to switch the scene MessageContainer mc; mc.messageType = ChatManagerScript.MessageType.Game_CharacterSelection; mc.message = modeNo.ToString(); mc.data = map; mc.senderUserIGN = ""; chatManager.PublicChatChannel_Send(ref party_PartyName, ref mc); } } /// <summary> /// To inform others member the host quite the character selection /// </summary> public void InParty_ReturnCharacterSelectionToMainMenu(){ if (party_InParty) { //Send Message to switch the scene MessageContainer mc; mc.messageType = ChatManagerScript.MessageType.Game_ReturnFromCharacterSelection; mc.message = ""; mc.data = ""; mc.senderUserIGN = ""; chatManager.PublicChatChannel_Send(ref party_PartyName, ref mc); } } /// <summary> /// To inform others about match making start /// </summary> public void InParty_StartMatchMaking(){ if (party_InParty) { //Send Message to switch the scene MessageContainer mc; mc.messageType = ChatManagerScript.MessageType.Party_MatchMaking; mc.message = ""; mc.data = ""; //This the mode ID mc.senderUserIGN = ""; chatManager.PublicChatChannel_Send(ref party_PartyName, ref mc); } } /// <summary> /// To inform others about match making cancel /// </summary> public void InParty_CancelMatchMaking(){ if (party_InParty) { //Send Message to switch the scene MessageContainer mc; mc.messageType = ChatManagerScript.MessageType.Party_MatchMaking_Cancel; mc.message = ""; mc.data = ""; //This the mode ID mc.senderUserIGN = ""; chatManager.PublicChatChannel_Send(ref party_PartyName, ref mc); } } #endregion #region Helper /// <summary> /// To update party count /// This will call on everyone /// </summary> /// <param name="count">Players Count</param> /// <param name="userIDs">Player List</param> /// <param name="relatedUser">The related user for this callback</param> public void Party_UpdateInPartyCount(int count, bool isUnsubscribe, ref HashSet<string> userIDs, ref string relatedUser){ party_TotalPlayer = count; //Update party user list party_List_PlayerList = userIDs; //If is unsubscribe then need to remove that player information if(isUnsubscribe){ //Check is host still in list, if not mean need to disband party and etc if (party_List_PlayerList.Contains(party_Leader_UserID) == false) { InParty_LeftParty(); } else{ //If left 1 player in party then disband party also if (party_TotalPlayer == 1) { InParty_LeftParty(); }else{ //if leader still exists and not 1 players left, then remove the related user info for(int i = 0; i < count; i++){ if(party_List_PlayerInfo[i].id.Equals(relatedUser)){ party_List_PlayerInfo.RemoveAt(i); break; } } } } }else{ //This is subscribe event } } void Party_ClearCache(){ party_PartyName = ""; Party_SetPartyLeader(false); party_List_PlayerInfo = null; } /// <summary> /// To handle the received party message /// </summary> /// <param name="message"></param> public void Party_ReceiveMessage(ref MessageContainer message){ switch(message.messageType){ case ChatManagerScript.MessageType.Game_CharacterSelection: //which mean switch character selection menu if(!party_Leader){ //Only call if u are not leader int mode = Int32.Parse(message.message); mainMenuScript.Panel_Party_MainMenuToHeroSelection(mode, ref message.data); //Message.Data contain the map name } break; case ChatManagerScript.MessageType.Game_ReturnFromCharacterSelection: if (!party_Leader) { mainMenuScript.Panel_StartGameHeroSelection_To_MainMenu(); } break; case ChatManagerScript.MessageType.Party_MatchMaking: if(!party_Leader){ mainMenuScript.MatchMaking_Party_OtherClientsStart(); } break; case ChatManagerScript.MessageType.Party_MatchMaking_Cancel: if(!party_Leader){ mainMenuScript.MatchMaking_Party_CancelMatchMaking(); } break; } } /// <summary> /// To handle the received party message /// </summary> /// <param name="senderID"></param> /// <param name="message"></param> public void Party_ReceiveMessage(ref string senderID, ref MessageContainer message) { switch (message.messageType) { case ChatManagerScript.MessageType.Game_CharacterSelection: //which mean switch character selection menu case ChatManagerScript.MessageType.Game_ReturnFromCharacterSelection: case ChatManagerScript.MessageType.Party_MatchMaking: case ChatManagerScript.MessageType.Party_MatchMaking_Cancel: Party_ReceiveMessage(ref message); break; } } /// <summary> /// To set is player in party /// </summary> /// <param name="inParty"></param> /// <param name="partyID"></param> void Party_SetInParty(bool inParty, ref string partyID){ party_InParty = inParty; //Update on local storage PlayerPrefs.SetInt(ConstStringContainer.party_InParty_Key, (party_InParty)?1:0); if(inParty){ PlayerPrefs.SetString(ConstStringContainer.party_PartyName_Key, partyID); }else{ PlayerPrefs.SetString(ConstStringContainer.party_PartyName_Key, ""); } } /// <summary> /// To set is player in party /// </summary> /// <param name="inParty"></param> void Party_SetInParty(bool inParty){ party_InParty = inParty; //Update on local storage PlayerPrefs.SetInt(ConstStringContainer.party_InParty_Key, (party_InParty)?1:0); if(inParty){ PlayerPrefs.SetString(ConstStringContainer.party_PartyName_Key, ""); }else{ PlayerPrefs.SetString(ConstStringContainer.party_PartyName_Key, ""); } } void Party_SetPartyLeader(bool partyLeader){ party_Leader = partyLeader; PlayerPrefs.SetInt(ConstStringContainer.Party_PartyLeader_Key, (party_Leader)?1:0); } #endregion }
Photon Custom Serializationusing System.Text; using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using UnityEngine; public enum PhotonEventCode : byte { Respawn = 0, PortalGemDropIn = 1, GameStart = 2 } public class PhotonGeneralManager : MonoBehaviourPunCallbacks, IPunOwnershipCallbacks{ //Singleton public static PhotonGeneralManager instance; // Start is called before the first frame update void Start(){ instance = this; PhotonPeer.RegisterType(typeof(MessageContainer), (byte)'A', SerializeChatMessage, DeserializeChatMessage); } #region Se-DeSerialize Chat Message public static short SerializeChatMessage(StreamBuffer outStream, object playerScoreType) { MessageContainer messageC = (MessageContainer)playerScoreType; short messageLength = (short)Encoding.UTF8.GetBytes(messageC.message).Length; short dataLength = (short)Encoding.UTF8.GetBytes(messageC.data).Length; short senderNameLength = (short)Encoding.UTF8.GetBytes(messageC.senderUserIGN).Length; int byteLength = 2 + 2 + 2 + messageLength + dataLength + senderNameLength + 4; byte[] bytes = new byte[byteLength]; int index = 0; Protocol.Serialize(messageLength, bytes, ref index); //Length of the message Protocol.Serialize(dataLength, bytes, ref index); //Length of the data Protocol.Serialize(senderNameLength, bytes, ref index); //Length of sender name System.Array.Copy(Encoding.UTF8.GetBytes(messageC.message), 0, bytes, index, messageLength); //Message index += messageLength; System.Array.Copy(Encoding.UTF8.GetBytes(messageC.data), 0, bytes, index, dataLength); //Data index += dataLength; System.Array.Copy(Encoding.UTF8.GetBytes(messageC.senderUserIGN), 0, bytes, index, senderNameLength); //sender name index += senderNameLength; Protocol.Serialize((int)messageC.messageType, bytes, ref index); //Bot hero ID outStream.Write(bytes, 0, byteLength); //write stream return (short)(byteLength); } public static object DeserializeChatMessage(StreamBuffer inStream, short length) { MessageContainer messageC; int index = 0; //Get the length of the string data byte[] strLenByte = new byte[2]; short strLenMessage, strLenData, strLenSenderName; //Read the size of message length inStream.Read(strLenByte, 0, 2); Protocol.Deserialize(out strLenMessage, strLenByte, ref index); //Read the size of the data strLenByte = new byte[2]; inStream.Read(strLenByte, 0, 2); index = 0; Protocol.Deserialize(out strLenData, strLenByte, ref index); //Read the size of the sender name strLenByte = new byte[2]; inStream.Read(strLenByte, 0, 2); index = 0; Protocol.Deserialize(out strLenSenderName, strLenByte, ref index); //Initialize the bytes to receive the rest int byteLength = strLenMessage + strLenData + strLenSenderName + 4; byte[] bytes = new byte[byteLength]; inStream.Read(bytes, 0, byteLength); index = 0; //Receive Message var userIDBytes = new byte[strLenMessage]; System.Array.Copy(bytes, index, userIDBytes, 0, strLenMessage); messageC.message = Encoding.UTF8.GetString(bytes, index, strLenMessage); index += userIDBytes.Length; //Receive data var dataBytes = new byte[strLenData]; System.Array.Copy(bytes, index, dataBytes, 0, strLenData); messageC.data = Encoding.UTF8.GetString(bytes, index, strLenData); index += dataBytes.Length; //Receive the sender name var senderBytes = new byte[strLenSenderName]; System.Array.Copy(bytes, index, senderBytes, 0, strLenSenderName); messageC.senderUserIGN = Encoding.UTF8.GetString(bytes, index, strLenSenderName); index += senderBytes.Length; //Receive Message Type int messageType; Protocol.Deserialize(out messageType, bytes, ref index); //Get the no of the message type messageC.messageType = (ChatManagerScript.MessageType)messageType; return messageC; } #endregion }
1 -
TeohTc
Bro You just save me from headache about party system in photon. This is the best way a to create party system.Friends, there are three types you may create a party system in photon
1. This method (best) but need to pay for photon chat also.
2. Creating a playfab group and constantly update group info for every 4 seconds to not to reach the client api limit. (Performance consuming method)
3. Creating a " staging room" in lobby and invite friend friends to room, when everyone ready masterclient leaves room and search for game room with exepected user and then send roomname toteammates and then they can join with him. ( This method hard to implement and may acquire some error while implementing)0