Sign In Register

How can we help you today?

Start a new topic
Answered

Getting Real Time player by peer ID

Hello


While following the Real-Time chat tutorial I decided to allow for drop-in/drop-out. 


When a player connects, I'd like to update the cached player list on the client. I'm guessing the best place to do this would be within this listener


  private void OnPlayerConnectedToGame(int _peerId)

    {

        Debug.Log("GSM | Player Connected, " + _peerId);

        // TODO Add this to the cached RTSessionInfo?

        AddPlayerToList(int _peerID);

    }


Then it should be a case of adding them to the list


    public void AddPlayerToList(int _peerID)

    {

        // Here i would create a new RTPlayer

        RTPlayer playerToAdd = new RTPlayer("Insert Correct Name", "Insert ID", _peerID);

        playerList.Add(playerToAdd);

    }



However, I need to get the Display Name and ID of the player. 


How do I do this? I tried looking up the API and figured 'GetPlayer' was what I wanted. 


https://docs.gamesparks.com/api-documentation/realtime-api/rtsession.html#getplayer


I can't seem to figure out how to actually use that function though.


Thanks


Jim


Best Answer

Hi Jim,


If you notice in the Real Time Tutorial sample. The DisplayName of each player is given to each of the clients via the MatchFoundMessage, the Real Time component really should only be concerned with handling data transmission via the peerId. What I would recommend is listening for a MatchUpdatedMessage which will contain the data of any new players including the DisplayName and PlayerId then using this data to update the playerList. I would reserve OnPlayerConnect for actually handling the event of a player connecting to the Real Time Session, like Spawning a new player object in scene. Does that make sense?


Kind regards,

 - Steve


Answer

Hi Jim,


If you notice in the Real Time Tutorial sample. The DisplayName of each player is given to each of the clients via the MatchFoundMessage, the Real Time component really should only be concerned with handling data transmission via the peerId. What I would recommend is listening for a MatchUpdatedMessage which will contain the data of any new players including the DisplayName and PlayerId then using this data to update the playerList. I would reserve OnPlayerConnect for actually handling the event of a player connecting to the Real Time Session, like Spawning a new player object in scene. Does that make sense?


Kind regards,

 - Steve

Hi Steve


Thanks a lot for the help! Does MatchUpdatedMessage only work if the real time session hasn't already started? I'm trying to update the list when the game is already running


I'm using this


 

   void Start()
    {
        GameSparks.Api.Messages.MatchUpdatedMessage.Listener += MatchUpdated;
    }

 


and then this

    private void MatchUpdated(GameSparks.Api.Messages.MatchUpdatedMessage _message)
    {
        //GetSessionInfo().AddPlayerToList()
        foreach (GameSparks.Api.Messages.MatchUpdatedMessage._Participant player in _message.Participants)
        {
            string _ID = player.Id;

            if (!(GetSessionInfo().GetPlayerList().Exists(p => p.id == _ID)))
            {
                string _displayName = player.DisplayName;
                string _id = player.Id;
                int _peerID = (int)player.PeerId;

                RTPlayer playerToAdd = new RTPlayer(_displayName, _id, (int)_peerID);

                GetSessionInfo().GetPlayerList().Add(playerToAdd);
                playerAdded(playerToAdd);
            }          
        }
    }

 No luck unfortunately!



Hi Jim,


No you should be able to receive the MatchUpdatedMessage during an active Real Time session. Do you've any further information that could help use diagnose this issue? Do you get any error logs? How are you going about updating the Match?


Kind regards,

 - Steve

Hi


Thanks again for the quick reply! 


No errors to speak of. I've added a breakpoint in Visual Studio at the start of my 'MatchUpdated' method. It doesn't get fired. 


I haven't gone out my way to update the match though, so perhaps I'm missing something? Here is my lobbymanager code 


 

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using GameSparks.Api.Responses;
using GameSparks.Core;
using System.Text;
using System.Linq;

public class LobbyManager : MonoBehaviour {

    public Text userID, connectionStatus;
    public InputField userNameInput, passwordInput;
    public Button loginButton, matchMakingButton, startGameButton;
    public GameObject loginPanel;

    public Text matchDetails;
    public GameObject matchDetailsPanel;

    public GameObject playerListPanel;
    public Text playerList;

    private RTSessionInfo tempRTSessionInfo;
    private string userName;
    void Start()
    {
        connectionStatus.text = "No Connection";
        // Hide Buttons 
        playerListPanel.SetActive(false);
        matchMakingButton.gameObject.SetActive(false);
        startGameButton.gameObject.SetActive(false);

        // Listeners
        loginButton.onClick.AddListener(Login);
        matchMakingButton.onClick.AddListener(MatchMake);
        startGameButton.onClick.AddListener(StartGame);

        // Set up callback using Lambda that will update connection status text if we can or can't connect to GameSparks
        GS.GameSparksAvailable += (isAvailable) =>
        {
            if (connectionStatus != null)
            {
                if (isAvailable == true)
                {
                    connectionStatus.text = "GameSparks Connected";
                }
                else
                {
                    connectionStatus.text = "GameSparks Disconnected";
                }
            }         
        };
      
        GameSparks.Api.Messages.MatchNotFoundMessage.Listener = (message) =>
        {
            playerList.text = "No Match Found";
        };

        GameSparks.Api.Messages.MatchFoundMessage.Listener += OnMatchFound;
    }

    private void OnMatchFound(GameSparks.Api.Messages.MatchFoundMessage _message)
    {
        Debug.Log("Match Found!");
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.AppendLine("Match Found...");
        sBuilder.AppendLine("Host URL: " + _message.Host);
        sBuilder.AppendLine("Port: " + _message.Port);
        sBuilder.AppendLine("Access Token: " + _message.AccessToken);
        sBuilder.AppendLine("MatchID: " + _message.MatchId);
        sBuilder.AppendLine("Participants: " + _message.Participants.Count());
        sBuilder.AppendLine("_______________________________");
        sBuilder.AppendLine();
        foreach(GameSparks.Api.Messages.MatchFoundMessage._Participant player in _message.Participants)
        {
            sBuilder.AppendLine("Player: " + player.PeerId + " User Name: " + player.DisplayName);
        }
        playerList.text = sBuilder.ToString();


        tempRTSessionInfo = new RTSessionInfo(_message, userName); // The match data is stored until the RT session instance is created

        matchMakingButton.gameObject.SetActive(false);
        startGameButton.gameObject.SetActive(true); // Pay attention to the order these appear in.
    }

    /// <summary>
    /// Pass the stored RTSessionInfo, created when a match is found, to the GameSparksManager
    /// </summary>
  
    private void Login()
    {
        userName = userNameInput.text;
        GameSparksManager.instance.AuthenticateUser(userNameInput.text, passwordInput.text, OnRegistration, OnAuthentication);
    }

    private void MatchMake()
    {
        GameSparksManager.instance.FindPlayers();
        playerList.text = "Searching For Players";
    }

    private void StartGame()
    {
        if (tempRTSessionInfo == null)
        {
            Debug.LogError("LM | No RTSessionInfo exists, has a match been found?");
        }
        GameSparksManager.instance.StartNewRTSession(tempRTSessionInfo); //tempRTSessionInfo used to be in here
    }

    private void OnRegistration(RegistrationResponse _resp)
    {
        userID.text = "UserID: " + _resp.UserId;
        connectionStatus.text = "New User Registered";

        loginPanel.SetActive(false);
        loginButton.gameObject.SetActive(false);
        matchMakingButton.gameObject.SetActive(true);
        playerListPanel.SetActive(true);
    }

    private void OnAuthentication(AuthenticationResponse _resp)
    {
        userID.text = "UserID: " + _resp.UserId;
        connectionStatus.text = "User Authenticated";
        loginPanel.SetActive(false);
        loginButton.gameObject.SetActive(false);
        matchMakingButton.gameObject.SetActive(true);
        playerListPanel.SetActive(true);
    }
}

 

Hi


Just to follow up. I had a look at the MatchUpdateMessage in the SDK documentation and it states. This would suggest to me that it wouldn't get sent when the match has been made? Maybe I'm wrong though!


MatchUpdatedMessage

A message indicating that there has been an update to a pending match request, but it is not yet complete

Hi Jim,


I think the MatchUpdated is not getting triggered because you are not updating the match. If no MatchUpdatedMessage is received that listening method is never going to fire. I would recommend you set up a Real Time Session as you would normally then in the Test Harness with a separate user join the already active match, this should trigger the MatchUpdatedMessage and hence update the client with the new player details of the player that just joined from the Test Harness.


Hope this helps,

 - Steve

I'm able to join with the game I've made. It doesn't trigger the listener.


I tried doing this in test harness. No luck joining?

{
 "@class": ".FindMatchResponse",
 "error": {
  "action": "UNKNOWN"
 }
}

{
 "@class": ".FindMatchRequest",
 "action": "",
 "matchGroup": "",
 "matchShortCode": "MULTIPLAYER_TUTORIAL",
 "skill": 0
}



{
 "@class": ".MatchmakingResponse",
 "error": {
  "action": "UNKNOWN"
 }
}

{
 "@class": ".MatchmakingRequest",
 "action": "",
 "customQuery": {},
 "matchData": {},
 "matchGroup": "",
 "matchShortCode": "MULTIPLAYER_TUTORIAL",
 "participantData": {},
 "skill": 0
}

Hi Jim,


Is the match set up as a drop in / drop out match? I think what happened there is the 3rd player trying to join has set up a new instance of the match. This documentation here might help clear this up.


Kind regards,

 - Steve

Hi Steve


Yeah the match is a drop in / drop out. 


I don't know how / what was different with my last attempt i but got the MatchUpdatedMessage to fire by stripping it back. For anyone who comes across this thread, heres the code I used


I set up a simple listener


ChatManager.cs

    private void test(GameSparks.Api.Messages.MatchUpdatedMessage _message)
    {      
        chatLogOutput.text += "\n MatchUpdatedMessage";
    } 

And also I set up simple listeners for OnPlayerConnectedToGame & OnPlayerDisconnected for gameSparksRTUnity.Configure just for testing purpose.


GameSparksManager.CS


    gameSparksRTUnity.Configure(response,
            (peerId) => { OnPlayerConnectedToGame(peerId); },
            (peerId) => { OnPlayerDisconnected(peerId); },
            (ready) => { OnRTReady(ready); },
            (packet) => { OnPacketRecieved(packet); }
            );

 

    private void OnPlayerConnectedToGame(int _peerId)
    {
        Debug.Log("GSM | Player Connected, " + _peerId);
       
        if (chatManager == null)
        {
            chatManager = GameObject.Find("Chat Manager").GetComponent<ChatManager>();
        }
        chatManager.PlayerConnected(_peerId);
    }

    private void OnPlayerDisconnected(int _peerId)
    {
        Debug.Log("GSM | Player Disconnected, " + _peerId);
        if (chatManager == null)
        {
            chatManager = GameObject.Find("Chat Manager").GetComponent<ChatManager>();
        }
        chatManager.PlayerDisconnected(_peerId);      
    }

ChatManager.cs

    public void PlayerDisconnected(int PeerID)
    {
        chatLogOutput.text += "\n" + PeerID + " DISCONNECTED";
    }

    public void PlayerConnected(int PeerID)
    {
        chatLogOutput.text += "\n" + PeerID + " CONNECTED";
    }

 Thanks!


Jim


1 person likes this

Was looking for exactly this thankyou! MatchUpdated is working fine so is your code.

Login to post a comment