IEnumerator ExecuteApiCallWithRetry <TResult>( Action <Action <TResult>, Action <PlayFabError> > apiAction, float busyIndicatorAfterSec = 1.0f, float messageBoxAfterSec = 4.0f, float fakeApiLatency = 0.0f, int fakeFailureCount = 0) { if (OfflineMode) { LastResult = null; yield break; } if (busyIndicatorAfterSec <= 0) { BusyScript.Instance.Show(); } float startTime = Time.time; float timeWaited = 0; int attempts = 0; TResult result = default(TResult); int fakeFailuresLeft = fakeFailureCount; while (true) { attempts++; bool callComplete = false; bool callSuccess = false; float apiCallRetryTime = 2.0f; Action <TResult> onSuccess = callResult => { Debug.Log(callResult); result = callResult; callComplete = true; callSuccess = true; }; Action <PlayFabError> onError = error => { string fullMsg = error.ErrorMessage; if (error.ErrorDetails != null) { foreach (var pair in error.ErrorDetails) { foreach (var eachMsg in pair.Value) { fullMsg += "\n" + pair.Key + ": " + eachMsg; } } } DebugText.SetLine("PF", error); Debug.Log(fullMsg); callComplete = true; }; float fakeLatency = fakeApiLatency + AdditionalGlobalLatency; if (fakeLatency > 0.0f) { yield return(new WaitForSeconds(fakeLatency)); } if (fakeFailuresLeft > 0 || SimulateConnectionLoss) { fakeFailuresLeft--; PlayFabError fakeError = new PlayFabError(); fakeError.Error = FakeErrorCode; fakeError.ErrorMessage = "Fake error for testing"; fakeError.HttpCode = 404; onError(fakeError); } else { apiAction(onSuccess, onError); } while (!callComplete) { yield return(null); timeWaited = Time.time - startTime; // Ensure indicator shown after initial delay if (timeWaited > busyIndicatorAfterSec) { BusyScript.Instance.Show(); } } if (callSuccess) { break; } timeWaited = Time.time - startTime; if (timeWaited >= messageBoxAfterSec) { BusyScript.Instance.Hide(); string message = "Hov, der er noget galt med forbindelsen!\n\nTryk <#ffffff>OK</color> for at prøve igen"; // i8n var wait = MessageBox.Instance.Show(message, MessageBox.Buttons.Ok, fadeInBackground: false); yield return(wait); } if (timeWaited >= busyIndicatorAfterSec) { BusyScript.Instance.Show(); } // Wait a bit so user can't spam retry yield return(new WaitForSeconds(apiCallRetryTime)); } DebugText.RemoveLine("PF"); BusyScript.Instance.Hide(); float timeTotal = Time.time - startTime; Debug.LogFormat("API ms: {0}", timeTotal); LastResult = result; yield return(result); // For CoroutineWithData }