- Home /
www freezing up Unity
Hello everyone, I've came across an issue to where I have lets say 20 Images That need to be changed on the fly. Now My problem is that unity is running this
Here's the for loop I use for grabbing the pictures.
for(int c = 0; c < 20;)
{
if(Application.isEditor)
{
WWW www = new WWW("file:///"+Application.dataPath+"/PowerPoints/BOP/Annular/Annular ("+(c+1)+").png");
StartCoroutine(FindFile(a,b,c,www));
if(isdone)
{
c+=1;
isdone = false;
}
}
and here's the code thats putting the pictures in there proper place
IEnumerator FindFile(int a, int b, int c, WWW www)
{
isdone = false;
//float counter = 0;
string[] NameOfFile = www.url.Split('/');
if(Application.isEditor)
{
NameOfTexture = NameOfFile[12];
}
else
{
NameOfTexture = NameOfFile[7];
}
while(www.progress != 1 )
{
ImageProgress = www.progress;
Debug.Log(www.progress);
//yield return www;
//yield return new WaitForEndOfFrame();
//yield return new WaitForSeconds(10);
}
if(www.progress == 1 && www.error == null)
{
isdone = true;
ImageProgress = www.progress;
ImagesFinished+=1;
ImageProgress = www.progress;
TextureInput[a,b,c] = www.texture;
www.LoadImageIntoTexture(TextureInput[a,b,c]);
TextureInput[a,b,c].Compress(false);
TextureInput[a,b,c].anisoLevel = 1;
TextureInput[a,b,c].mipMapBias = 0;
Debug.Log("DONE");
//yield return www;
//yield return new WaitForEndOfFrame();
}
//yield return new WaitForEndOfFrame();
yield return isdone;
//yield return new WaitForSeconds(5);
}
is there anyway I can get pictures to download and not freeze unity at start up, thanks
Answer by Guardian2300 · Oct 01, 2013 at 05:16 PM
Finally Got it, I have two IEnumerators and my for loop pauses now. Heres my new for loop.
for(int c = 0; c < TextureInput.GetLength(2);c++)
{
if(Application.isEditor)
{
//WWW www = new WWW("file:///"+Application.dataPath+"/PowerPoints/BOP/Annular/Annular ("+(c+1)+").png");
string Path = "file:///"+Application.dataPath+"/PowerPoints/BOP/Annular/Annular ("+(c+1)+").png";
yield return StartCoroutine(FindFile(a,b,c,Path));
//Debug.Log (www.progress);
}
else
{
//WWW www = new WWW("file:///"+(System.IO.Directory.GetCurrentDirectory().ToString())+"/PowerPoints/BOP/Annular/Annular ("+(c+1)+").png");
string Path = "file:///"+(System.IO.Directory.GetCurrentDirectory().ToString())+"/PowerPoints/BOP/Annular/Annular ("+(c+1)+").png";
yield return StartCoroutine(FindFile(a,b,c,Path));
//Debug.Log (www.progress);
}
//yield return new WaitForEndOfFrame();
}
and heres my new update FindFile
IEnumerator FindFile(int a, int b, int c, string Path)
{
WWW www = new WWW(Path);
string[] NameOfFile = www.url.Split('/');
//www.threadPriority = UnityEngine.ThreadPriority.High;
while(www.progress != 1)
{
ImageProgress = www.progress;
yield return new WaitForFixedUpdate();
//yield return new WaitForEndOfFrame();
//yield return new WaitForSeconds(1f);
//Debug.Log (www.progress);
}
yield return www;
if(Application.isEditor)
{
NameOfTexture = NameOfFile[12];
}
else
{
NameOfTexture = NameOfFile[7];
}
if(www.error == null)
{
ImagesFinished+=1;
ImageProgress = www.progress;
TextureInput[a,b,c] = www.texture;
www.LoadImageIntoTexture(TextureInput[a,b,c]);
TextureInput[a,b,c].Compress(false);
TextureInput[a,b,c].anisoLevel = 1;
TextureInput[a,b,c].mipMapBias = 0;
}
else
{
Debug.Log(www.error);
}
}
the yield return StartCoroutine prevents the for loop from loading FindFile too Fast, cause it seemed that speed was an issue and was trying to have it wait enough for it to show on the screen. Only problem is that framerate is a little bit slow at some points but not complaining, if threads could work for this this piece of code would be perfect for downloading. Thanks everyone for helping
Answer by ArkaneX · Sep 27, 2013 at 08:34 PM
You should just start a coroutine in your Start method and do your processing inside. After processing all textures, you can set some variable which might later be used e.g. inside Update method. Pseudocode:
bool _imagesLoaded = false;
void Start()
{
StartCoroutine(LoadFiles());
}
IEnumerator LoadFiles()
{
for(...)
{
WWW www = new WWW(...);
yield return www;
// here, www call finished, so you can retrieve texture and process it
}
_imagesLoaded = true;
}
void Update()
{
if(_imagesLoaded)
{
// do something
}
}
I suggest reading a bit more about coroutines at Unity Gems, and also to look at Unity Answers for some examples of using WWW.
EDIT: you can also use Texture2D.Load image. Example:
var bytes = System.IO.File.ReadAllBytes(filePath);
var tex = new Texture2D(1, 1);
tex.LoadImage(bytes);
so your saying this replace all of my for loops from within my other function into this function and have it called. I have more for loops I was using this one as an example
It's hard to tell you exactly what you need to do, without knowing your full code. The answer was a guidance how you could convert code from your question. It is not exactly the same, because my code waits until one image is loaded before it starts loading another, but you can of course modify it, by moving for loop into Start method, change LoadFiles() to LoadFile(string path) and then load only one file in this method.
As a general rule, you should create WWW instance inside coroutine, and then yield it. When it finishes executing request, then coroutine is resumed and your code will continue.
As a side note - if you're loading png/jpg from your application path, then you can also use Texture2D.LoadImage. Please look at updated answer for example.
if he trying to download images from the web coroutine will not solve the freeze. coroutine are not asynchronous and while the they run and the download didn't finished they will hold the main thread.
read this about coroutines: link text
@haim96 - coroutine is not asynchronous, true. But it doesn't mean it blocks main thread. When you yield, coroutine is paused and will be resumed depending on what you yielded, but other methods can be executed in the meantime without any problems. Otherwise yielding for example WaitForSeconds(10f) would have blocked main thread for 10 seconds. You can test it by yielding www for a big file, and see that your code from Update method is still running.
Btw - this is the same link as provided in my answer.
i didn't checked this on files and you might be right... unless the WWW wait for the whole file to download then it will freeze. i didn't noted you already posted the link...sorry.
Answer by haim96 · Sep 27, 2013 at 08:12 PM
this is where you should use threads. it's complicated and i'm not the man to tell you how to do that but basically thread should allow you to download images in one thread and keep unity doing something else in the same time.(for example showing progress bar or something...)
i hope it's help somehow...
I was trying to do that awhile back but the Editor wouldn't let me run the thread to do www being in Unity code and not c# code, if I were to use threads then I would have to use system io with it then would be a possibility