- Home /
Engine pauses/hangs when getting files via WWW
Unity 4.6.2f1 - Windows 7 and editor
Hello! I've set up scripts to load a selection of audio files from the user's music local library using WWW. Unfortunately, this seems to cause a short hang/pause in the engine for about 0.5 to 1 seconds in the editor and about 0.25 to 0.5 seconds in a Windows build. I'm currently only loading 2 OGG files of approximately 4mb.
The total time for the script to run is only 0.058 seconds. The first file takes 0.018 seconds and the second takes 0.03999 seconds. The files are the same size and actually the same files, but in separate directories.
Does anyone know:
Why the second file takes more than 2x the time to load even though it is the same file.
Why the engine pauses when getting the files via WWW. I am under the impression that WWW is asynchronous and the pause/hang time seems to be much greater than the actual time to load the files.
The Coroutine I use can be found below in case someone can point out my mistake or help me optimize it. Please note I have tested the times around the external function calls and they are all 0. The external function calls really just add the audioClip to a list in the PlayListController class and set some variables. Also note that the hang is not much different when only loading one file.
Thanks!
IEnumerator LoadTracks()
{
int counter = 0;
bool tracksToLoad = false;
foreach(LocalMusicTrack track in localMusicTrackList)
{
if (!track.isLoaded && track.isSelected)
{
tracksToLoad = true;
break;
}
}
if (tracksToLoad)
{
while (canvasGroup.interactable)
yield return new WaitForEndOfFrame();
PopUpMessage.instance.Instantiate(0.5f , 0.125f , "Loading tracks...");
//put this here to allow message to fade in (fade in time is 0.125f) but for some reason
//engine pauses sooner
yield return new WaitForSeconds(0.13f);
if (PlaylistController.instance.crossfadeTime < 5f)
PlaylistController.instance.crossfadeTime = 5f;
}
PlaylistController.instance.RemoveAllTracks();
float t_totalLoading = Time.time;
List<float> t_fileLoads =new List<float>();
foreach(LocalMusicTrack track in localMusicTrackList)
{
if (track.isLoaded && track.isSelected)
{
PlaylistController.instance.AddTrackToList(track.clip);
}
else if (track.isSelected)
{
AudioClip remoteClip = null;
string error = "";
bool isError = false;
if (!File.Exists(track.filePath))
{
error = "file not found: " + track.filePath;
isError = true;
}
else
{
string protocol = "file:///";
#if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IPHONE)
protocol = "file://";
#endif
var www = new WWW(protocol + track.filePath);
float dlStartTime = Time.time;
while (!www.isDone)
{
float elapsedTime = Time.time - dlStartTime;
if (elapsedTime > 300f)
{
error += "\ntimeout loading track: " + elapsedTime.ToString();
isError = true;
}
else
{
yield return www;
//yield return null;
//yield return new WaitForEndOfFrame();
}
}
dlStartTime = Time.time - dlStartTime;
t_fileLoads.Add(dlStartTime);
if (!isError)
{
remoteClip = www.GetAudioClip(false, false);
remoteClip.name = track.trackName + counter.ToString();
if (!string.IsNullOrEmpty(www.error))
{
error += "\nwww.error: " + www.error;
isError = true;
}
if (remoteClip.length < 5f)
{
error += "\nlength too short: " + remoteClip.length.ToString();
isError = true;
}
if (!remoteClip.isReadyToPlay)
{
error += "\nclip not ready: " + remoteClip.isReadyToPlay.ToString();
isError = true;
}
}
if (!isError && remoteClip != null)
{
track.isLoaded = true;
track.clip = remoteClip;
PlaylistController.instance.AddTrackToList(track.clip);
}
else
{
www.Dispose();
PopUpMessage.instance.Instantiate("Error loading track: " + track.trackName);
Debug.LogError("Error loading track: " + track.filePath + "\n" + error);
if (remoteClip == null)
{
Debug.LogError("REMOTE CLIP IS NULL!");
}
}
}
}
}
PlaylistController.instance.SetTimers();
string dOut = "\nfile load times: \n";
foreach (float tl in t_fileLoads)
{
dOut += "\t" + tl.ToString() + "\n";
}
t_totalLoading = Time.time - t_totalLoading;
Debug.LogWarning("t_totalLoading: " + t_totalLoading.ToString() + dOut);
}
}
Is the pause happening on the WWW call, or when you actually load the file? I had a similar issue a while back while trying to load JPGs on the fly. I had a horrible stutter when the file loaded. (In my case I solved it by saving my files in a pre-compressed format, so unity didn't have to convert them to DXT files on load, but there probably isn't a similar solution you can use in your case).
It's not at the WWW call either. I've checked everything in the script for bottlenecks and the only areas where time actually elapses is during the file loads, but those times are much smaller than the actual stutter in the game :( So it must be the file loads which is kinda crappy since I don't think there's anything I can do about that!
I think your "while (!www.isDone){}"
block may be slowing things down.
Is there a particular reason for it? Doesn't the WWW object timeout anyway? I'd try replacing that whole block with a yield return www
and then deal with any errors in www
rather than look for them while it's trying to load the file.
The block does a yield return www. I just tossed the extra 300 second timeout in there because my experience with previous engines. The reason for it is because I need the full file loaded before I want to add it to the playlist. Can you provide an example of what you mean? I tried simpler implementations previous to this and still had the same pause.
I can see that the block does a yield return www, that's why the while clause seems superfluous. It's not going to continue past that yield until the www call is done anyway (whether it's successful or not).
Example of what I mean is simply to replace your whole while
block with something like
yield return www;
if (string.IsNullOrEmpty( www.error ))
{
// handle error
}
else
{
// process response
}
Your answer
Follow this Question
Related Questions
How to supress a # into a path string 1 Answer
Wait for file download 1 Answer
How to upload a file from Android to my own website? 0 Answers
loading local file synchronically using WWW? 2 Answers
How To Know File Changed 2 Answers