1
\$\begingroup\$

Can anyone tell me if there is a async version of LoadImage() method? I found about Resources.LoadAsync, however the method doesnt work.

Thank you

\$\endgroup\$
  • \$\begingroup\$ When you say that Resources.LoadAsync "doesn't work," what result exactly are you seeing? Do you get a compile or runtime error? Does the returned ResourceRequest never complete? Does it complete but contain a null resource or a different resource than you wanted? Are you trying to load a file that is not one of your resource assets? We need specifics if we're going to help you solve this. \$\endgroup\$ – DMGregory Jan 12 '16 at 0:53
  • \$\begingroup\$ I am trying to load an image that is not in my resources assets. I have a large set of images (6GB). Do you think using www class could help ? The task I have is to visualize a part of a country in Unity. So I need a better method for replacing images on camera change than LoadImage(), because it is too slow. \$\endgroup\$ – Domen Lušina Jan 12 '16 at 1:04
  • \$\begingroup\$ Where are these images coming from if they're not bundled in your game's Assets folder? Are you downloading them from a server, or are they being provided by a user, or something else? \$\endgroup\$ – DMGregory Jan 12 '16 at 1:06
  • \$\begingroup\$ They are provided by a user \$\endgroup\$ – Domen Lušina Jan 12 '16 at 1:07
1
\$\begingroup\$

You're on the right track in the comments above when you ask whether the WWW class could help. This is how I've solved the problem in the past for asynchronously loading local image files as Texture2D data:

Texture2D _content;
Material _material;

// Call this with StartCoroutine(LoadTexture(path));
IEnumerator LoadTexture(string path)
{
    // Start the asynchronous load.
    var www = new WWW("file://" + path);

    // Let the game continue running until the texture has been loaded.
    yield return www;

    // Replace current content with loaded texture.
    if (_content != null)
        Destroy(_content);
    _content = www.texture;

    // Instantiate a copy of the material, 
    // and hang onto it so we can clean up when finished with it
    if (_material == null)
        _material = GetComponent<Renderer>().material;

    _material.mainTexture = www.texture;
}

void OnDestroy()
{
    // Clean up created instances
    // (these aren't immediately garbage-collected otherwise)
    if(_material != null)
         Destroy(_material);
    if(_content != null)
         Destroy(_content);
}

I don't know how much load-balancing Unity does on its own, but it might be good to avoid kicking off all 6GB of load requests at once. ;) Try pacing them out, so you only have a few requests running at a time, to avoid any major hitches.

\$\endgroup\$
  • \$\begingroup\$ In my experience, www.texture is 100% synchronous and blocks the main thread for a significant length of time with large textures (enough to cause framerate stutter). However, I was using www for web requests, not local requests. \$\endgroup\$ – cowlinator May 24 '16 at 17:53
0
\$\begingroup\$

You can fire off a C# thread to load the image from a file, and get as far as turning it into a color array, with which you can quickly set a texture. So assuming you have some class AsyncImage with a function loadMyImage() which sets a Color[] pixels member variable, you could do something like:

 Thread t = new Thread(new ThreadStart(asyncImage.LoadMyImage));
 t.Start();

Now in the update method of your script, or some coroutine that runs every few milliseconds:

if (asyncImage.pixels != null) {
  myTexture2d.SetPixels(asyncImage.pixels);
}

You have probably heard that Unity can't do threading, but it is only the case that most Unity objects will not function outside of the main thread. You can still fire off as many threads as you want and do whatever things you want in them, as long as you don't use those forbidden unity methods/objects. This may mean you have to roll your own image loading code, or find some open source code. It is possible the standard mono libraries will have what you need. You can see a similar example in my source where I am generating an image procedurally in the background here: https://github.com/jackmott/solescape/blob/master/Assets/src/MainMenu/MainMenuManager.cs

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.