WWW does not work in weplayer

Hi,

Here’s a code, it works fine in editor, but fails to download a file in webplayer mode.

For test purposes I run it from localhost, so there should be NO problem at all about same-origin policy or other restrictions.

How to make it work in webplayer?

IPacket[] responses = net.Packets.Fetch<PacketGate2UnityRegionResponse>();
int iRegion = -1;
foreach ( PacketGate2UnityRegionResponse re in responses )
{
	iRegion = re.region;
	Log.Console.Print( "Appeared in region {0}", iRegion );
	dlResources = new WWW( String.Format( "http://localhost/region{0}.resources.txt", iRegion ) );
}
// wait for download to complete
if ( dlResources != null )
{
	Log.Console.Print( "DL: {0}% errors: {1}", dlResources.progress*100, dlResources.error );
	if ( dlResources.error != null )
	{
		Log.Console.Write( dlResources.error );
		net.Disconnect();
		state = GameState.Disconnected;
	}
	else if ( dlResources.isDone )
	{
		string data = dlResources.data;
		filesToLoad = data.Split( new string[] { System.Environment.NewLine, "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries );
		loader = new ResourceLoader( filesToLoad, "http://localhost/{0}.unity3d" );
		state = GameState.Loading;
	}
}

This code is located inside a cycle run 30 times a second from a custom thread. (Thus, the state of dlReources is checked frequently)

236639--8466--$console_log_163.jpg

I’m missing the yield return dlResources; line in there that handles the yielding of the coroutine until the download is done or alternatively the creation of further Coroutines to handle the different downloads independently as you potentially create more than one

within the editor it potentially just works because the code executes slower due to the “testing” environment, but normally its guaranteed that the download will never ever be done in milliseconds, already getting the tcp connection up and handshaking done takes more time than you have available in there

I cannot create a couroutine, since the class is NOT inherited from a MonoBehaviour. Instead the code is run 30 times a second by a custom thread

void Update( int timePrevFrame, int timeUpdate ) {
switch ( state )
{
// Handle some cases here
case GameState.QueryResources:
// The CODE quoted 
break;
// Some other states are handled here
}

I fear in this case you will have to do some indepth rewrites.
Unity functions must not be called from custom threads, the must only be called from the main thread. Unity isn’t thread safe and you are basically generating a massive access violation there.
You can basically be happy that it is “only” not working.

If you have it then in the main thread and call it from somewhere (can basically be any callback, coroutine, etc) you need to push the www into a queue and check it on each call if a download is done and act correspondingly.

your code posted is primarily pretty wrong and stands no chance to work from what I see.

  1. It potentially generates more than one WWW call, but only ever checks the last one

  2. it checks the state of the download instantly after starting the web request, that can realistically never succeed

Thanks for reminding about unity’s thread un-safety. That code worked since I moved it to UnityUpdate function of the same class, which gets called from main camera’s update.

As for the points why the code should not work, let me disagree. It did work in editor somehow yet =)

Due to our interaction protocol, the packet containg the region should not arrive more than once, so multiple WWW instances should not happen. Yet according to your advice, I’ve improved the code, now it looks a bit better

if ( dlResources == null ) 
{
  // Learn what region has been assigned to us by server;
  dlResources = new WWW(...)
}
else
{
  // download resource list required to play there
}

Yet, again =)) Though the download should NOT succeed right after the request, it actually did!

Anyway, the problem is solved. Thank you.

In the editor its much more likely that it can succeed within the timeframe, because the editor executes the code slower due to the checks it does etc.

In the webplayer it might work at the time as you use localhost, but if real latency comes in I wouldn’t bet on it anymore.