Coroutine either/or setup

Hey guys,

I was wondering if there is a way to create a yield return in a coroutine that will either wait for a certain time frame or wait till a download is finished. Here is what I have at the moment:

IEnumerator LoadAtlas(string url, string atlasFile)
{
	WWW www = new WWW(url + atlasFile);
		
	yield return new WaitForSeconds(5.0f);
		
	if(www.error != null || !www.isDone)
	{
		if(www.error != null)
		{
			Debug.Log(www.error);
		}
		else
		{
			Debug.Log(atlasFile + " took too long to download");
		}
	}
	else
	{
		//snippet
	}
	www.Dispose();
	www = null;
}

I want to do something kind of like this:

IEnumerator LoadAtlas(string url, string atlasFile, Vector2 atlasDimensions)
{
	WWW www = new WWW(url + atlasFile);
		
	yield return www || new WaitForSeconds(5.0f);
		
	//snippet
}

But obviously that does not work. I just want to be able to do a simultaneous yield return that will return either www or new WaitForSeconds(5.0f), which ever finishes first basically.

Thanks for any help that you guys can give me.

Something like this?

IEnumerator download {
    while (!www.isDone) {
        yield return null
    }
}
// code to do once download is finished
downloadComplete = true;

Sort of, I wanted it to basically wait for one of the two conditions to finish first:

  1. www finish downloading
  2. WaitForSeconds runs out

I believe I have a pretty good idea on what to do. I will be posting back here once I see if my idea works or not.

[EDIT] Uh…we are actually considering this as a low priority for our project so I am going to finish the other features and I will be sure to post again on here when I have actually worked on it.

[BUMP] Ok I have solved it (only took an hour actually lol). Here is what I did (It will be in C#):

  1. Declare a private global variable for WWW and set it to null
WWW atlasWWW = null;
  1. Create an IEnumerator function with at most 1 parameter. This function will wait for a set number of seconds that you want to set. If it fails to download after the set time then that will mean that it took too long to download the file.
IEnumerator LoadAtlas(string url)
{
	Debug.Log("Loading From " + url);
		
	atlasWWW = new WWW(url);
		
	yield return new WaitForSeconds(5.0f);
		
	atlasWWW.Dispose();
	atlasWWW = null;		

	Debug.Log("Download took too long");
}
  1. Call StartCoroutine with the 1st parameter as the name of the function in string and 2nd parameter as the url
StartCoroutine("LoadAtlas", url);
  1. Create an Update function that will check if www is null. If it is not null then it will check to see if it is done downloading. You do not want to do this in the same if statement because then unity will give you the “NullReferenceException: Object reference not set to an instance of an object”. When the download is done you can then stop the coroutine where it is waiting for the set time to pass. This will not work if you did not call StartCoroutine with the function name as a string. After that you can do your usual checking for error message setting up your data.
void Update()
{
	if(atlasWWW != null)
	{
		if(atlasWWW.isDone)
		{
			StopCoroutine("LoadAtlas");
			if(atlasWWW.error != null)
			{
				Debug.Log(atlasWWW.error);
				
				atlasWWW.Dispose();
				atlasWWW = null;
			}
			else
			{
				//Set up your data here and be sure to dispose your www properly
				//RIGHT after you finish with it.
			}
		}
	}
}

Be sure to set your www to null when you are finished so that part of the code would not run again. I hope this helps anyone else that was in the same boat as me. Feel free to criticize my code and give me feedback on what I would need to do to make it look cleaner improve it’s performance :slight_smile: