简体   繁体   中英

Unity Google Play Games Create game with invitation problem

I can create games with invites, I can invite and accept invitations, the thing mostly works fine. The problem appears when I make a game for 3 or more people:

  • user A creates game with 3 people or 2 people at least
  • user A chooses to invite someone and then adds another person to auto-pick for the room
  • User A invites user B
  • User B accepts
  • They both wait until the "Start now" button appears
  • User B presses the start now button and OnRoomConnected() is called 3 times for some reason and the game doesn't start (the room was also never left as far as I can tell, because this user can't receive invitations anymore)
  • Nothing changes from the perspective of user A, he still waits for the game to start or search for another auto pick opponent

I made sure that the problem is not from my code. I created a separate simple project, that I used only for testing purposes and it does exactly the same thing. So I was starting to think maybe it's not a problem from my side and I didn't see similar problems on the internet. So I decided to ask here. What should I do? What could be the problem?

That's basically it. Even if I restrict the number of players to 3 or 4 (min and max number of players are equal, 3 or 4), it still lets me start the game prematurely and I have the same problem with OnRoomConnected() being called multiple times and the game doesn't start.

Thanks in advance. If you have a link or something that would help me solve this problem, it would be greatly appreciated.

Here's the basic code I used for logging in the game and creating a room.

public class GPGM : MonoBehaviour, RealTimeMultiplayerListener{

public static GPGM instance;
public static int target;

private void Awake()
{
    target = 60;
    QualitySettings.vSyncCount = 0;
    Application.targetFrameRate = target;

    if (instance == null)
    {
        DontDestroyOnLoad(gameObject);
        instance = this;
    }
    else if (instance != this)
    {
        Destroy(gameObject);
    }
}
// Use this for initialization
void Start () {
    Login();
}

// Update is called once per frame
void Update () {

}

public void Login()
{
    StartCoroutine(checkInternetConnection((isConnected) =>
    {
        LoginGPG();
    }));
}

IEnumerator checkInternetConnection(Action<bool> action)
{
    WWW www;
    www = new WWW("http://google.com");

    yield return www;

    if (!String.IsNullOrEmpty(www.error))
    {
        Debug.Log("DebugM | no internet connection");
        action(false);
    }
    else
    {
        Debug.Log("DebugM | There IS connection");
        action(true);
    }
}

public void LoginGPG()
{
    PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder().WithInvitationDelegate(OnInvitationReceived).Build();
    PlayGamesPlatform.InitializeInstance(config);
    PlayGamesPlatform.DebugLogEnabled = true;
    PlayGamesPlatform.Activate();
    Debug.Log("DebugM | LoginGPG");
    Auth();

}

public void Auth()
{
    Debug.Log("DebugM | Auth");
    try
    {
        //doesn't work sometimes for some reason. It gives null data if success is false
        //reason for false success is unknown
        Social.localUser.Authenticate((bool succes) =>
        {
            if (succes)
            {
                Debug.Log("DebugM | Logged in");
            }else
            {
                Debug.Log("DebugM | authentication failed");
            }
        });
    }
    catch (Exception e)
    {
        Debug.Log("DebugM | Auth() has failed with error: " + e.Message);
    }
}

public void OnInvitationReceived(Invitation invitation, bool shouldAutoAccept)
{
    StartCoroutine(InvitationCo(invitation, shouldAutoAccept));
}

Invitation mIncomingInvitation;
IEnumerator InvitationCo(Invitation invitation, bool shouldAutoAccept)
{
    yield return new WaitUntil(() => SceneManager.GetActiveScene().name == "Lobby");

    Debug.Log("DebugM | Invitation has been received!!!");
    //StartCoroutine(LM.LoadingAnim());
    if (shouldAutoAccept)
    {
        Debug.Log("DebugM | Should auto accept: TRUE");
        PlayGamesPlatform.Instance.RealTime.AcceptInvitation(invitation.InvitationId, instance);

    }
    else
    {
        // The user has not yet indicated that they want to accept this invitation.
        // We should *not* automatically accept it. Rather we store it and 
        // display an in-game popup:
        Debug.Log("DebugM | Should auto accept: FALSE");
        Lobby LM = FindObjectOfType<Lobby>();
        LM.invPanel.SetActive(true);
        mIncomingInvitation = invitation;
    }
}

public void AcceptGoogleInv(GameObject panel)
{
    if (mIncomingInvitation != null)
    {
        // show the popup
        //string who = (mIncomingInvitation.Inviter != null &&
        //    mIncomingInvitation.Inviter.DisplayName != null) ?
        //        mIncomingInvitation.Inviter.DisplayName : "Someone";
        Debug.Log("DebugM | Invitation has been accepted");
        PlayGamesPlatform.Instance.RealTime.AcceptInvitation(mIncomingInvitation.InvitationId, instance);
        panel.SetActive(false);
    }
}

public void CreateQuickRoom()
{
                PlayGamesPlatform.Instance.RealTime.CreateWithInvitationScreen(1, 3, 1, instance );
}

public void OnRoomSetupProgress(float percent)
{
    Debug.Log("OnRoomSetupProgress()");
    PlayGamesPlatform.Instance.RealTime.ShowWaitingRoomUI();
}

public void OnRoomConnected(bool success)
{
    SceneManager.LoadScene("Game");
    Debug.Log("DebugM | Room conected");
}

public void OnLeftRoom()
{
    throw new NotImplementedException();
}

public void OnParticipantLeft(Participant participant)
{
    throw new NotImplementedException();
}

public void OnPeersConnected(string[] participantIds)
{
    throw new NotImplementedException();
}

public void OnPeersDisconnected(string[] participantIds)
{
    throw new NotImplementedException();
}

public void OnRealTimeMessageReceived(bool isReliable, string senderId, byte[] data)
{
    throw new NotImplementedException();
}}

Edit (pictures): This is when I wait for the last auto pick slot to fill (it works like this only when people were invited to the game)

The game goes to lobby for the person who pressed start and the others still wait for the last autopick even if 1 player practically left the room

You can do it like:

public void OnRoomConnected (bool success)
   {
     if (success)
      {
        //Start the game here
        SceneManager.LoadScene("Game");
        Debug.Log("DebugM | Room conected");
      }
     else
      {
        //Do somthing else.
      }
   }

or the best way to do it by checking connected participans count.

public void OnPeersConnected (string[] participantIds)
    {
      List<Participant> playerscount = PlayGamesPlatform.Instance.RealTime.GetConnectedParticipants();
      if (playerscount != null && playerscount.Count > 1)//this condition should be decided by you.
        {
          //Start the game here
          SceneManager.LoadScene("Game");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM