question

Andrey Lytvynov avatar image
Andrey Lytvynov asked

Unity 3D doen't handle PlayFab Async callback.

Hi Guys

I can't find the way out of waiting for callback returned from PlayFab before continuing the execution of other unity c# functions. PlayFab API is asyn but unity functions are not they all are sync, my function where I am calling the PlayFab API ends before it gets results and then executes other functions that require for those results, the request sent but unity doesn't wait for the result. The thread doesn't work. Please help

 public void GetPlayerProfile() {
	//getting success call
        PlayFabClientAPI.GetPlayerProfile(new GetPlayerProfileRequest()
        {
            PlayFabId = PlayFabId,
            ProfileConstraints = new PlayerProfileViewConstraints()
            {
                ShowDisplayName = true,
            }
        }, (result) => // "at this point we are exiting the function without waiting for result"
        {
            //doing soemthing with code
        }, (error) =>
        {
            //doing soemthing with code
        });
    }

Thanks

Regards

unity3dPlayer Inventory
10 |1200

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

Sarah Zhang avatar image
Sarah Zhang answered

PlayFab Unity SDK uses the Coroutine which is concurrent asynchronous. If you are using the PlayFab Unity3D SDK, the call back function should work well. If you need to use the result of this API in the other functions, you need to call the functions in the "(result)" call back function.

As the sample code in the QuickStart shows, Debug.log() needs to be called in the callback function.

using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;

public class PlayFabLogin : MonoBehaviour
{
    public void Start()
    {
        if (string.IsNullOrEmpty(PlayFabSettings.staticSettings.TitleId)){
            /*
            Please change the titleId below to your own titleId from PlayFab Game Manager.
            If you have already set the value in the Editor Extensions, this can be skipped.
            */
            PlayFabSettings.staticSettings.TitleId = "42";
        }
        var request = new LoginWithCustomIDRequest { CustomId = "GettingStartedGuide", CreateAccount = true};
        PlayFabClientAPI.LoginWithCustomID(request, OnLoginSuccess, OnLoginFailure);
    }

    private void OnLoginSuccess(LoginResult result)
    {
        Debug.Log("Congratulations, you made your first successful API call!");
    }

    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your first API call.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());
    }
}
2 comments
10 |1200

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

Andrey Lytvynov avatar image Andrey Lytvynov commented ·

It is not the best way of doing, I want to use results but not inside the rest API it is a dirty way of working. I want to get it and then pre-process it in other function like this, THanks for your answer, I will look into Coroutine it should have something for me.

public function() {
	getUserInformationFromPlayFab() // wait doesn't work
	//doSomeStafWithInformation - at this point we fail because playfab hasn't returned the result at the time, it requested but not returned. So this staf needs to go to the getUserInformationFromPlayFab result section, which is dirty way of working.
	callOtherFunction()

}
public callOtherFunction(){
	//do the staff
}
0 Likes 0 ·
Sarah Zhang avatar image Sarah Zhang Andrey Lytvynov commented ·

Thanks for clarifying your thoughts. The answer above shows an example of how the Playfab Unity SDK works. SDK is essentially a series of encapsulation associate with API calls. You can modify the SDK on your own to meet your requirements.

1 Like 1 ·
scottadams avatar image
scottadams answered

The result section will need to set a global flag to let your other code know it completed.

You can check those flags during the Unity Update() or FixedUpdate() FUNCTION calls and then do the next step as desired.

1 comment
10 |1200

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

Sarah Zhang avatar image Sarah Zhang commented ·

Thanks for sharing.

0 Likes 0 ·
Dor avatar image
Dor answered

You can run your playfab calls inside a coroutine and use yield instructions to wait for values to be updated. For example, consider the following:

bool flag = false;

IEnumerator CallPlayFabApi()
{

	var request = new ExamplePlayFabRequest() {/* Initialization */ };
	PlayFabClientAPI.ExecuteExamplePlayFabRequest(
	request,	result => flag = true,
	error => flag = true
	);

	yield return new WaitWhile(() => !flag);

	// Dosomething
}

This is very basic example. In my case, I have encapsulated playfab calls into scriptable objects so they could be passed on easily from scene to scene, save local data thus removing unneccessary calls, notify me when new data arrives and implement an interface to know if they are safe to read.

 
              
2 comments
10 |1200

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

Dor avatar image Dor commented ·

The boolean doesn't have to be in global space and you can cache the result instead.

0 Likes 0 ·
Sarah Zhang avatar image Sarah Zhang commented ·

Thanks for sharing.

0 Likes 0 ·

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.