I am trying to load an audio file from disk and would like to do it synchronously via UnityWebRequest. Is this possible? Any hack?
That’s kind of a strange request. “I like this class, except it doesn’t make my whole game lock up while it’s running. Can I change it so that my whole game locks up?”
I guess it depends on how Unity implemented UnityWebRequest behind the scenes. If it implicitly runs on another thread, you could write a loop that specifically blocks the main thread while waiting for it to complete. However, if it works more like a coroutine, where it does incremental work at a particular time on the main thread, then blocking the main thread would prevent it from ever completing. I’m not sure which is the case.
One could perhaps “simulate” the main thread being blocked by pausing everything else that’s happening in the game, but…why?
You could probably find some other API for reading a file from disk that happens to be synchronous. If the file in question is present at build time (and doesn’t need to be substitutable later), one option might be to put it in your Resources folder and use Resources.Load.
This is a very bad idea. I would recommend you better explain why you need this, maybe we can suggest a better solution instead.
That being said, this should be possible by spinning a loop until isDone property returns true.
Note that the solution only applies to audio file and may not apply to other types (assuming, that by audio file you mean UnityWebRequestMultimedia.GetAudioClip).
Thanks guys for the responses!
Sure, I need to read a .wav file at runtime. My app allows users to import audio files.
Cool, I’ll give that a try.
But why does it need to be a synchronous read?
Alright, I got it to work with the loop hack. Thanks!
Yes, we had to use UnityWebRequestMultimedia to load local media files and there are no other synchronous tools for this. Fortunately, you can make UnityWebRequest synchronous using this workaround:
Debug.Log(Time.frameCount);
webRequest.SendWebRequest();
while (!webRequest.isDone) { }
Debug.Log(Time.frameCount);
One reason you might want to do this is if you need to read a file in the StreamingAssets folder during an otherwise synchronous operation on platforms like Android, where you can’t access StreamingAssets with the regular File API.
With UnityWebRequest being the only readily available option to read from StreamingAssets on these platforms, you can end up in a situation where you have to convert an entire code path to coroutines just so that you can read a file. (or use the hack above, but that feels… dirty).
Are there any alternatives to UnityWebRequest for reading from the StreamingAssets folder on Android?
I guess you could use Addressables or the await keyword to make async coding easier to type and read.
If all you want is an API for your code to interact with the Audio file in a synchronous way you could wrap the file loading in a wrapper object which caches your api calls and executes them once the actual file is loaded. That way you can just use it synchronously. Though that’s quite a bit of extra coding work and you are basically mirroring and already existing API. If you stack these things it may become hard to debug and reason about when things are actually loaded. This only abstracts away the async parts. The load will still be async. If you actually need the contents of the file then this won’t do you any good.