I’m working on a project that requires scene changes to be remote-controlled. My thought was to have the app call a WWW every few seconds, and change the scene based on the response. I’m running into issues, though: WWW tends to run into errors on a regular basis on android, and then it spends 60 seconds waiting to time-out before it will start another WWW and be able to get the scene change command. I’ve tried stopping the coroutine, disposing of the WWW, and starting a second coroutine, but nothing works on Android. Can anyone suggest a better way of going about this?
My code thus far:
void Update(){
if(Time.time - lastCheck > 2F && runRupdater == true){
StartCoroutine(getCurrentScene ());
}
}
//Get the current scene, then continue to check every two seconds.
IEnumerator getCurrentScene (){
float thisCheck = Time.time;
lastCheck = Time.time;
string urlToCheck = "http://myurl/where.php?pi="+whichPresentation;
WWW getScene = new WWW(urlToCheck);
yield return getScene;
if(Time.time - thisCheck > 3F){
getScene.Dispose();
yield break;
}
if(getScene.text != "null"){
if(currentScene != int.Parse(getScene.text)){
int.TryParse(getScene.text, out currentScene);
StartCoroutine(ActOnScene ());
}
}
}
If anyone stumbles on this, on android devices the WWW.Dispose method won’t return immediately after called but will hang until the timeout is done or an error occurs; if the connection is slow (on the subway 4 example) this can lasts up to 60 seconds.
What I ended up doing was creating a WWW disposer that disposes WWWs when they are done; this prevents the device from freezing.
public class WWWDisposer : MonoBehaviour
{
private List<WWW> m_wwwsToDispose = new List<WWW>();
void Awake()
{
GameObject.DontDestroyOnLoad(gameObject);
}
public void AddWWWToDispose(WWW _toDispose)
{
m_wwwsToDispose.Add(_toDispose);
}
void Update()
{
for(int i = 0; i < m_wwwsToDispose.Count; i++)
{
if(m_wwwsToDispose*.isDone)*
* public static WWWDisposer GetDisposer()* * {* * GameObject gameObject = GameObject.Find("wwwDisposer");* * if(gameObject == null) {_ gameObject = new GameObject("wwwDisposer");* * gameObject.AddComponent(); } return gameObject.GetComponent(); } }* This is useful if you want to for example wait a maximum of 5 seconds to retrieve an asset from the server, if the request times out, you can use an embedded low res asset or a cached one._
I don’t think you can override the default timeout, but remember that your coroutine can yield on values other than the WWW. You could instead check each frame (or every X seconds) if the WWW isDone.
If the WWW doesn’t finish within whatever time limit you track, your coroutine can do something to handle that appropriately.