- Home /
WaitForSeconds doesn't seem to work.
I'm trying to delete everything in my inventory and then adding items to it using MySQL and PHP scripts. However, it seems the my coroutine deletes everything, but does not execute the code to add items even after I put a WaitForSeconds. In fact, it doesn't even output or reach Debug.Log("Finished Delete"). I have ways around this, such as formatting my database to where it doesn't have to delete everything first, but I'm genuinely interested in coroutine and would like to understand them more.
void OnApplicationQuit()
{
Save();
}
void Save ()
{
StartCoroutine(DeleteInventory());
}
IEnumerator DeleteInventory()
{
Debug.Log("Doing Delete");
WWWForm form = new WWWForm();
form.AddField("PlayerID", player.PlayerID);
//Calls my PHP script to delete everything in the player's inventory.
WWW w = new WWW("http://house.riekumar.me:8080/DeletePlayerInventory.php", form);
//I wait for 5 seconds, because that should be plenty of time to finish deleting
//everything in the inventory.
yield return new WaitForSeconds(5f);
//Doesn't execute anything here and below.
Debug.Log("Finished Delete");
for (int i = 0; i < controller.Player.Inventory.Length; ++i)
{
if (controller.Player.Inventory[i].GetItemInfo() != null)
StartCoroutine(SaveInventory(controller.Player.Inventory[i].GetItemInfo().ID));
}
}
Solution:
IEnumerator DeleteInventory()
{
Debug.Log("Starting to Delete...");
WWWForm form = new WWWForm();
form.AddField("PlayerID", player.PlayerID);
WWW w = new WWW("http://house.riekumar.me:8080/DeletePlayerInventory.php", form);
while (!w.isDone && string.IsNullOrEmpty(w.error))
{
Debug.Log("Not Done");
}
Debug.Log("Finished deleting...");
for (int i = 0; i < controller.Player.Inventory.Length; ++i)
{
if (controller.Player.Inventory[i].GetItemInfo() != null)
StartCoroutine(SaveInventory(controller.Player.Inventory[i].GetItemInfo().ID));
}
yield return null;
}
Watch out, what you wrote as solution hangs the main thread in the while loop until the database query finished, because you don't give back control by calling yield return null;
in the body of the while loop!
I am wondering, does the coroutine ever have a chance to continue, if you start it from the OnApplicationQuit? I mean there aren't going to be any more frames to wait for right?
Hahaha, good spot! In a build, the coroutine will start to execute and then never continue after the first yield return... which would also explain the use of while() without yield return!
Answer by nathanvj · Feb 08, 2018 at 09:57 PM
Use yield return w
to wait for completion. That might solve the problem.
Example code:
private IEnumerator DeleteInventory()
{
Debug.Log("Starting to delete...");
WWWForm form = new WWWForm();
form.AddField("PlayerID", player.PlayerID);
//Calls my PHP script to delete everything in the player's inventory.
WWW w = new WWW("http://house.riekumar.me:8080/DeletePlayerInventory.php", form);
// Wait till WWW finishes
yield return w;
// Continue with script
Debug.Log("Finished deleting...");
for (int i = 0; i < controller.Player.Inventory.Length; ++i)
{
if (controller.Player.Inventory[i].GetItemInfo() != null)
StartCoroutine(SaveInventory(controller.Player.Inventory[i].GetItemInfo().ID));
}
}
Weird. Does the 'Finished deleting...' get printed if you completely remove the yield return w?
Nope, unfortunately. I'm going to update my question in a sec, so I might be leaving something that could be interfering out.
Edit: Question is updated, my OnApplicationQuit() is calling my save, but I don't know if that would cause an issue.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
WWW Form C# on Android 0 Answers
Coroutines and states 1 Answer
WWW DownloadManager, C# 1 Answer