- Home /
[Closed]Unity crash, while/for loop
Hi,
I am trying to create a script to use kinect to measure the user's arm lenght. As kinect's values fluctuate a lot when doing that, in my script I was making 150 measures and then calculating an average value - that would be admited as his real arm lenght throughout the rest of the code. (Just so you know, the calibration is supposed to start when you put your left hand in your hip - and you should have your right arm completely extended sideways)
The problem is that, as soon as I play the game, Unity crashes... Don't really get why...
var calibrate : boolean = true;
var calibrationValuesNumber : int = 150;
var calculate : boolean = false;
var valueSum : float = 0.0f;
//lenght of the users arm during calibration
var rightArmLenghtAprox : float;
//lenght of the users arm after calibration
var rightArmLenght : float;
//distance between the user's left hand and his hip
var leftDistanceToHip : float;
function Start () {
calibrationFunction();
}
function calibrationFunction() {
while (calibrate == true) {
leftDistanceToHip = Vector3.Distance(leftHand.transform.position, leftHip.transform.position);
//This means that a user was detected and the skeleton has "expanded" and the distance between the body parts is no longer 0
if (calculate == false && leftDistanceToHip > 0.23) {
calculate = true;
Debug.Log("calculating...");
}
if (calculate == true && leftDistanceToHip <= 0.23) {
Debug.Log("calibrating... stay still");
for (var i : int = 1; i <= calibrationValuesNumber; i++) {
rightArmLenghtAprox = Vector3.Distance(rightHand.transform.position, rightElbow.transform.position) + Vector3.Distance(rightElbow.transform.position, rightShoulder.transform.position);
valueSum = valueSum + rightArmLenghtAprox;
if (i == calibrationValuesNumber) {
rightArmLenght = valueSum / calibrationValuesNumber;
calibrate = false;
Debug.Log("Average is: " + rightArmLenght.ToString());
}
}
}
}
}
Thanks in advance
Please post the whole script. There are a ton of undeclared variables here, and I need to test in Unity.
I would assume it is crashing because of it never exiting that while loop that is called on start. Why not run that function, $$anonymous$$us the while loop, in update until calibrate goes to false. That way the entire execution of your application isnt hung waiting for that while loop to finish.
Click on the game object this script is attached to and verify that 'calibrationValuesNumber' is not zero.
The update function is a while loop. I agree with brianruggieri. Try this:
function Update() {
if( calibrate == true )
{
// do your stuff
}
else
{
// whatever other stuff
}
..............
}
The only problem in using the update function is that every frame it will be checking if that value is still the same or not... :/ it is a waste of processing power and I only need it to run once at the beggining
Answer by ExplodingCookie · Jul 24, 2013 at 08:39 PM
I have had this issue a lot, my temporary solution is to use this line at the end of the while like this
while(true) {
...
yield WaitForSeconds(0.001);
}
For some reason, Unity never crashes as long as there is a yield in the script
~ExplodingCookie
This is a very bad solution, as in UnityScript it will de facto transform the function into a Coroutine which will eat up resources. If a while loop is infinite, debug it, don't yield it.
I actually think this would work, because it would give time for "calibrate" to get to "false" before starting another "while loop".
Answer by jovino · Jul 24, 2013 at 08:47 PM
The condition in the for loop
i <= calibrationValuesNumber;
don't let execute the last if:
if (i == calibrationValuesNumber)
I think you want to do this:
if (i == calibrationValuesNumber - 1)
Of course you can change also the loop:
for (var i : int = 1; i == calibrationValuesNumber; i++) {
If you are going to call the calibrationFunction more times (not only in Start(), I have to agree too with agobrianruggieri, do it in Update() function.
I will call it more times, but just when the user chooses it in the menu :/ putting it in the update function would work, but it's kind of a waste
Yeah, it can be a waste then. You checked the conditions like I said? I think it crashes because it never get out of the loop...
The conditions where correct, but yes there is a problem with the "while loop"... I think it might be an overload of information (like I posted in the solution below) and that way it would crash because there was too much information to process (also meaning it would never get to te end of one of the loop).
Answer by LostInTime · Jul 28, 2013 at 07:11 PM
First of all, thanks everyone for your feedback. I got it sorted out. I think that the problem was that while "calibrate" was "true", every frame the function would start the "while loop" and that would mean an immensity of measures because "calibrate" wasn't getting to "false" until another "while loop" had started - imagine 100 "while loops" running at the same time and each checking for their conditions (I am not sure though...).
So I took away the "while loop" and now it looks like this:
function calibrateFunction() {
leftDistanceToHip = Vector3.Distance(leftHand.transform.position, leftHip.transform.position);
if (calculate == false && leftDistanceToHip > 0.23) {
calculate = true;
Debug.Log("calculating... Put your left hand in your hip and extend your right arm sideways");
}
if (calculate == true && leftDistanceToHip <= 0.23) {
Debug.Log("calibrating... stay still");
for (var i : int = 1; i <= calibrationValuesNumber; i++) {
leftDistanceToHip = Vector3.Distance(leftHand.transform.position, leftHip.transform.position);
rightArmLenghtAprox = Vector3.Distance(rightHand.transform.position, rightElbow.transform.position) + Vector3.Distance(rightElbow.transform.position, rightShoulder.transform.position);
valueSum = valueSum + rightArmLenghtAprox;
if (i == calibrationValuesNumber) {
rightArmLenght = valueSum / calibrationValuesNumber;
calibrate = false;
calculate = false;
Debug.Log("Average is: " + rightArmLenght.ToString());
return;
}
}
}
if ((calculate == false && leftDistanceToHip <= 0.23) || (calculate == true && leftDistanceToHip > 0.23)) {
yield WaitForSeconds(0.1);
repeatFunction();
}
}
function repeatFunction() {
calibrateFunction();
}
This way, with just "if"s, it will just repeat the function until both "calibrate" and "calculate" values become "false" and it works PERFECTLY :D
But still, isn't there a way, inside the function itself, to start it again without the need to create a second function ("repeatFunction")...?
Thanks again
Now I look back at this post and I realize the patience and understanding people had to have to answer to this post x) Thanks everyone
Your answer
Follow this Question
Related Questions
DoWhile Loop is crashing Unity. Why? 2 Answers
A node in a childnode? 1 Answer
Installing Unity 3D 4.3.4 on Windows 8.1 2 Answers
Crash app unity 4.5.5f1 on nexus 7 (Android 4.4.4) 0 Answers
Unity Crashing on Second function call 0 Answers