question

Berk Unal avatar image
Berk Unal asked

Matchmaking Active server connection

Hello,

I'm using the example project from Natepac (https://github.com/natepac/playfabmirrorgameexample) for my server which works with Unity/Mirror.

I have added Playfab matchmaking on top of this example project but I have an issue with "connecting" clients to the allocated servers by matchmaking - getmatch result IP and port. Whenever I use getmatch IP and port on mirror NetworkManager IP and apathy/telepathy ports, the server becomes "active" status but the "player" count area is always 0. However, on my client, the mirror says it's "connected" but it doesn't spawn the player object.

If I call RequestMultiplayerServerRequest to get the IP and Port, then it works okay. Mirror connects, the player spawns. But the server stays on standby state.

I can only connect/spawn player (I'm not sure if it's a connection problem, I just can't spawn the player object to the client scene) to a server if it is on a "standby" state. But the matchmaking turning it into an "active" state instantly and I can not spawn the player object.

I just can't figure out the problem for a very long time now. What changes between "standby" and "active" states so that it blocks mirror from spawning player game object?

Do I need to pass some sort of information to the server to spawn the player after matchmaking turns it to an "active" state?

I have looked through everything there is about playfab matchmaking, I just need to know what am I missing?

I hope this is the correct ID: D92B4.

Ps. I'm logging in with Device ID / googleplay ID before trying any of this and passing the Entity ID for matchmaking.

I'm attaching my matchmaking script as well. Thank you very much!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.MultiplayerModels;
using TMPro;
using System.Linq;
using Mirror;

public class Matchmaker : MonoBehaviour
{
    public TelepathyTransport telepathyTransport;
    public ApathyTransport apathyTransport;

    public NetworkManager networkManager;
    public ClientStartUp clientStartUp;
    public Configuration configuration;

    [SerializeField] private GameObject playMatchmakingButton;
    [SerializeField] private GameObject leaveQueueButton;
    [SerializeField] private TMP_Text queueStatusText;

    private string ticketId;
    private Coroutine pollTicketCoroutine;

    private const string QueueName = "DefaultQueue";

    public string playfabTCPPortName;


    public void StartMatchmaking()
    {
        playMatchmakingButton.SetActive(false);
        queueStatusText.text = "Submitting Ticket!";
        queueStatusText.gameObject.SetActive(true);

        PlayFabMultiplayerAPI.CreateMatchmakingTicket(
            new CreateMatchmakingTicketRequest
            {
                Creator = new MatchmakingPlayer
                {
                    Entity = new EntityKey
                    {
                        Id = PlayfabManager.EntityId,
                        Type = "title_player_account"
                    },

                    Attributes = new MatchmakingPlayerAttributes
                    {
                        DataObject = new
                        {
                            latencies = new object[]
                            {
                                new
                                {
                                    region = "NorthEurope",
                                    latency = 4999
                                }
                            }
                        }
                    },
                    
                },

                GiveUpAfterSeconds = 120,
                
                QueueName = QueueName
            },
            OnMatchmakingTicketCreated,
            OnMatchmakingError
       );
    }

    private void OnMatchmakingTicketCreated (CreateMatchmakingTicketResult result)
    {
        ticketId = result.TicketId;
        pollTicketCoroutine = StartCoroutine(PollTicket());

        leaveQueueButton.SetActive(true);
        queueStatusText.text = "Ticket Created";
    }

    private void OnMatchmakingError(PlayFabError error)
    {
        Debug.Log("Matchmaking Error!");
        Debug.Log(error.GenerateErrorReport());
    }


    private IEnumerator PollTicket()
    {
        while (true)
        {
            PlayFabMultiplayerAPI.GetMatchmakingTicket(
                new GetMatchmakingTicketRequest
                {
                    TicketId = ticketId,
                    QueueName = QueueName
                },
                OnGetMatchmakingTicket,
                OnMatchmakingError
                );

            yield return new WaitForSeconds(6);
        }
    }

    private void OnGetMatchmakingTicket(GetMatchmakingTicketResult result)
    {
        queueStatusText.text = "Status: " + result.Status;

        switch (result.Status)
        {
            case "Matched":
                StopCoroutine(pollTicketCoroutine);
                StartMatch(result.MatchId);
                break;

            case "Canceled":
                break;
        }
    }


    private void StartMatch(string matchId)
    {
        queueStatusText.text = "Starting Match";

        PlayFabMultiplayerAPI.GetMatch(
            new GetMatchRequest
            {

                MatchId = matchId,
                ReturnMemberAttributes = true,
                QueueName = QueueName,

            },

            OnGetMatch,
            OnMatchmakingError
            );
    }

    private void OnGetMatch(GetMatchResult result)
    {
        queueStatusText.text = result.Members[0].Entity.Id + "\n" + "VS" + "\n" + result.Members[1].Entity.Id;
        

        int tcpPort = 0;
        
       

        foreach (Port port in result.ServerDetails.Ports)
        {
            if (port.Name == playfabTCPPortName)
                tcpPort = port.Num;
        }


        configuration.ipAddress = result.ServerDetails.IPV4Address;
        configuration.port = (ushort)(result.ServerDetails.Ports.Where(s => s.Name == "game_port").FirstOrDefault()?.Num ?? 7777);

        networkManager.networkAddress = result.ServerDetails.IPV4Address;
        telepathyTransport.port = (ushort)(result.ServerDetails.Ports.Where(s => s.Name == "game_port").FirstOrDefault()?.Num ?? 7777);
        apathyTransport.port = (ushort)(result.ServerDetails.Ports.Where(s => s.Name == "game_port").FirstOrDefault()?.Num ?? 7777);

        networkManager.StartClient();
    }

unity3dMatchmaking
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Seth Du avatar image
Seth Du answered

The example project from Natepac is not an official example provided by PlayFab, hence it will take time for us to understand how it works. Please refer to our official Mirror sample from MpsSamples/UnityMirror at master PlayFab/MpsSamples (github.com).

The server state is managed by PlayFab Server, and data like GameState is received via GSDK (PlayFabMultiplayerAgentAPI) in the server build. Locally changing the GameState variable will not have effects on the server. please feel free to try the official sample and let me know if you have any other questions.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.