3 for loops and a IF crashes when the if is true
So i was writing a automated terrain colorizer when i noticed something strange. in my script i have 3 for loops. the 2 first goes from 0 to 1024 for the x and y values of the terrain. while the last for loop is for every texture i want to paint with. This runs fine. However, when i add a IF- statement underneath and it returns true, Unity freezes and refuses to respond. while the if statement returns false, the program runs fine....
after many attempts i decided to see if i could replicate the problem in a new project. so i wrote this wich also crashes try for yourself (put the script on any gameobject and set the variables to true when you press play) :
using UnityEngine;
using System.Collections;
public class ProblemCodeClass : MonoBehaviour {
public bool run = true;
public bool theProblem = true;
void Update () {
if (run){
for(int x = 0; x < 1024; x++) {
for (int y = 0; y < 1024; y++) {
for (int z = 0; z < 4; z++) {
Debug.Log("I run this fine");
if (theProblem){
Debug.Log("Im not getting here....");
}
}
}
}
run = false;
}
}
}
Any ideas why or how this can be fixed?
Does your sample code also freeze the Unity editor? And "I'm not getting here" isn't going to show because theProblem
is false. If this isn't replicating your freeze problem then you'll need to show your actual code.
This does indeed freeze unity up. I have tested on several computes with same result. I'm aware that theProblem
is false in the code here. It was meant to be copied and tested, and to show that it runs fine while run
is true.
As mentioned below, the Debug.Log calls are going to cause things to run for quite some time - that's a lot of logging. Remove those and your sample code will run fine. So you need to show us the actual problem code - you have something in there that's affecting the loop.
Answer by brunocoimbra · Jul 14, 2016 at 07:09 PM
Well, I did a little test with my old PC (Intel Core i5 2400, 8GB ram, onboard graphics) using the Unity 5.3.5f1 and everything seemed to freeze when I hit Play with "theProblem" setted to true. But then I had an idea! Change your test code to this:
using UnityEngine;
using System.Collections;
public class ProblemCodeClass : MonoBehaviour
{
public int firstLoop = 4;
public int secondLoop = 4;
public int thirdLoop = 4;
public bool run = true;
public bool theProblem = true;
void Update()
{
if (run)
{
for (int x = 0; x < firstLoop; x++)
{
for (int y = 0; y < secondLoop; y++)
{
for (int z = 0; z < thirdLoop; z++)
{
Debug.Log("I run this fine");
if (theProblem)
{
Debug.Log("Im not getting here....");
}
}
}
}
run = false;
}
}
}
I turned everything to false in inspector, then hit play. It runs.
While playing, setted run
to true. It runs with the correct output.
Still while playing, setted theProblem
to true, then setted`run`to true again. Evertyhing is fine.
If I change firstLoop
to 1024, then set everything to true again, the editor freezes for almost 1 minute then shows me the correct output.
If I change secondLoop
to 1024 too, then set everything to true again, the editor freezes for some minutes then shows me the correct output.
So, this is not a Unity problem, it just did not finished the task. Debug.Log
is somewhat expensive, so wait some time if you have a low profile PC to se if it remais frozen.
As an extension to my answer, comment both Debug.Log
calls. You will see that even with 1024x1024x4 it will not freeze. Uncomment one of them and it will take some time to unfreeze. Uncomment both and the time spent is almost twice. It is because you will be calling 4.194.304 times the Debug.Log
method.
the problem is not my computers speccs. the problem is still there when i do not have the Debug.log aswell. which my original code does not have. as i said the problem is that when the IF returns true, the program freezes. the original code had accualy several if -statements that didnt cause any problems. But when i decided to add that bool check it just freezes
Your code does not have Debug.Log
but has some heavier code (I believe). Without the ACTUAL code we can't be sure, but remember: it will run 4.194.304 times, it will be expensive anyway.
@Runnetty to confirm that it is NOT frozen, but only taking some time, use that code: using UnityEngine; using System.Collections;
public class Test : $$anonymous$$onoBehaviour
{
public int firstLoop = 1024;
public int secondLoop = 1024;
public int thirdLoop = 4;
public int updateInterval = 100;
private int currentLoop;
private int loopsCount;
private float startTime;
private void Update()
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Return))
{
StopAllCoroutines();
StartCoroutine(IRun());
}
}
private IEnumerator IRun()
{
// int can hold values up to 2.147.483.647
loopsCount = firstLoop * secondLoop * thirdLoop;
currentLoop = 0;
startTime = Time.time;
for (int x = 0; x < firstLoop; x++)
{
for (int y = 0; y < secondLoop; y++)
{
for (int z = 0; z < thirdLoop; z++)
{
currentLoop++;
if (currentLoop % updateInterval == 0)
{
UpdateConsole();
yield return null;
}
}
}
}
UpdateConsole();
}
private void UpdateConsole()
{
#if UNITY_EDITOR
var logEntries = System.Type.GetType("UnityEditorInternal.LogEntries,UnityEditor.dll");
var clear$$anonymous$$ethod = logEntries.Get$$anonymous$$ethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
clear$$anonymous$$ethod.Invoke(null, null);
Debug.Log(string.Format("Completed {0:0.00}% in {1:0.00} seconds.", $$anonymous$$athf.InverseLerp(0, loopsCount, currentLoop) * 100, Time.time - startTime));
#endif
}
}
Your answer
Follow this Question
Related Questions
simplest way to add a minimum distance or gap between instantiated objects 1 Answer
A key will not respond 1 Answer
Problem with rotation to mouse position 0 Answers
Unity 5.2 messing up car 0 Answers
Level Start error :/ 1 Answer