Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Unity - Load a file on background thread

I need to load a file in my application and since it is big ( around 250MB) I need to perform this loading off the main thread. What is more, because assets on Android are not stored in a regular directory, but a jar file, I need to use WWW or UnityWebRequest class.

I ended up with helper method like that:

public static byte[] ReadAllBytes(string filePath)
{

    if (Application.platform == RuntimePlatform.Android)
    {
        var reader = new WWW(filePath);
        while (!reader.isDone) { }

        return reader.bytes;
    }
    else
    {
        return File.ReadAllBytes(filePath);
    }
}

The problem is I cannot use it on background thread - Unity won't allow me to create WWW object there. How can I create a method like this, which will read those bytes on current thread?

like image 642
Michał Powłoka Avatar asked Sep 15 '26 19:09

Michał Powłoka


2 Answers

just put your while loop inside a CoRoutine and while your request is not done to a yield return. when it is done call a method where you want to use your data:

IEnumerator MyMethod()
{
    var reader = new WWW(filePath);
    while (!reader.isDone) 
    { 
        yield return; // <- use endofFrame or Wait For ore something else if u want
    }
    LoadingDoneDoData(reader.bytes);
}

void LoadingDoneDoData(bytes[] data)
{
    // your Code here
}
like image 197
Vampirasu Avatar answered Sep 17 '26 08:09

Vampirasu


I think you can use something like

public static async void ReadAllBytes(string filePath, Action<byte[]> successCallback)
{
    byte[] result;
    using (FileStream stream = File.Open(filePath, FileMode.Open))
    {
        result = new byte[stream.Length];
        await stream.ReadAsync(result, 0, (int)stream.Length);
    }

    // Now pass the byte[] to the callback
    successCallback.Invoke();
}

(Source)

Than I guess you can use it like

TheClass.ReadAllBytes(
    "a/file/path/",

    // What shall be done as soon as you have the byte[]
    (bytes) =>
    {
        // What you want to use the bytes for
    }
);

I'm no multi-threading expert but here and also here you can find more examples and how to's for async - await with Unity3d.


Alternatively also the new Unity Jobsystem might be interesting for you.

like image 42
derHugo Avatar answered Sep 17 '26 08:09

derHugo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!