Search Unity

Coroutines Halting on iOS

Discussion in 'Scripting' started by rharriso, Sep 18, 2014.

  1. rharriso

    rharriso

    Joined:
    Apr 9, 2014
    Posts:
    6
    I'm trying to load textures in the background using WWW. Here is a snippet.

    Code (CSharp):
    1.  
    2.     void Start(){
    3.           StartCoroutine("LoadBgImage");
    4.     }
    5.  
    6.     private IEnumerator LoadBgImage(){
    7.         string path = volume.BackgroundImageUrl;
    8.  
    9.         WWW www = new WWW (path);
    10.         Debug.Log ("Do the request");
    11.         yield return www;
    12.         Debug.Log ("request complete");
    13.         Texture2D tex = www.texture;
    14. }
    15.  
    16.  
    This works on desktop, but when I try on iOS the application halts at the yield return statements.
     
  2. Krysalgir

    Krysalgir

    Joined:
    Aug 30, 2010
    Posts:
    95
    What do you mean it halts ?
    It crashes?
    What does your log says?

    It can be a problem of URL, you do not check after the request that the www has been successful (check for www.errors).
     
  3. rharriso

    rharriso

    Joined:
    Apr 9, 2014
    Posts:
    6
    When I say it halts. I mean the log on line 12 never runs.
    The log on line 10 does.

    This is also the case if I yield return null.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    That's the part that makes this behavior really strange, and makes it possible you've encountered a Unity bug.

    Try this test case. What is its output?
    Code (csharp):
    1.  
    2. void Start() {
    3. StartCoroutine(Tester1());
    4. StartCoroutine("Tester2");
    5. }
    6. public IEnumerator Tester1() {
    7. Debug.Log("Tester1a");
    8. yield return null;
    9. Debug.Log("Tester1b");
    10. }
    11. public IEnumerator Tester2() {
    12. Debug.Log("Tester2a");
    13. yield return null;
    14. Debug.Log("Tester2b");
    15. }
    16.  
    (Checking to see if there's a difference between the string version and the "natural" version of StartCoroutine. I use the natural version all the time on iOS with no issues, but I've never used the string version on iOS, so it's possible the difference is between those variants.)

    If you put this on an object in your scene and see anything less than all four Debug statements, then I would say you should use it as a repro case for a bug report to UT.

    Finally, which version of Unity are you on?
     
  5. rharriso

    rharriso

    Joined:
    Apr 9, 2014
    Posts:
    6
    I'm on version 4.5.2.

    The output of those couroutines is complete
    Tester1a
    Tester1b
    Tester2a
    Tester2b
     
  6. rharriso

    rharriso

    Joined:
    Apr 9, 2014
    Posts:
    6
    The www error string is empty.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,743
    Something else is going on. Your script works fine on my iPad. You might want to check your URL, your network connection, etc.

    I copied your script and modified it with my own URL and got it to work just fine in an empty Unity scene with a camera and the script hung on that camera.

    I'm using Unity 4.5.2f1 and XCode 5.0.2.

    Kurt

    Code (csharp):
    1.  
    2. usingUnityEngine;
    3. usingSystem.Collections;
    4.  
    5. //10:07AM9/18/2014
    6. //http://forum.unity3d.com/threads/coroutines-halting-on-ios.269220/
    7.  
    8. publicclassForum269220 : MonoBehaviour
    9. {
    10. Texture2Dtex;
    11.  
    12. voidStart()
    13. {
    14. StartCoroutine("LoadBgImage");
    15. }
    16.  
    17. privateIEnumeratorLoadBgImage()
    18. {
    19. stringpath = "http://www.plbm.com/private/launchprocedure.jpg";
    20.  
    21. WWWwww = newWWW (path);
    22. Debug.Log ("Do the request");
    23. yieldreturnwww;
    24. Debug.Log ("request complete");
    25. tex = www.texture;
    26. }
    27.  
    28. voidOnGUI()
    29. {
    30. Rectr = newRect (0, 0, Screen.width, 0);
    31.  
    32. if (tex != null)
    33. {
    34. r.height = (r.width * tex.height) / tex.width;
    35. GUI.DrawTexture( r, tex);
    36. }
    37. else
    38. {
    39. r.height = Screen.width * 0.10f;
    40. GUI.Label ( r, "Loading...");
    41. }
    42. }
    43. }
    44.  
     
  8. rharriso

    rharriso

    Joined:
    Apr 9, 2014
    Posts:
    6
    This isn't being cause by the URL.

    This coroutine is being launched right after a new scene is loaded. And it doesn't matter what is in the coroutine, it halts on the first yield.
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,743
    Try making start() return an Ienumerator too (that makes unity treat it as a coro), then do a yield for 1 sec before issuing your www request... Just poking in the dark with that idea...

    Kurt
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Instead of doing yield return www, you make be able to get better information by writing your own yielding loop. For one example:

    Code (csharp):
    1.  
    2. WWW www = new WWW("path");
    3. while (www.texture == null) {
    4. Debug.Log("Progress: "+www.progress.ToString("#.00"));
    5. if (www.error != "" && www.error != null) Debug.LogWarning("Error: "+www.error);
    6. //any other information you want to test it with, can go here
    7. yield return 0;
    8. }
    9. Debug.Log("Finished, with a texture");
    10.