- Home /
Unity crashes when using while
Unity crashes when I trigger this part of the script:
function AutoHit (){
script.canmove = false;
while(target == null){
if(Input.GetKey(KeyCode.Mouse0)){
var hit : RaycastHit;
var ray : Ray = camera.main.ScreenPointToRay (Input.mousePosition);
Physics.Raycast(ray, hit);
ObjectHit = hit.collider.gameObject.tag;
if (hit.rigidbody != null){
if (ObjectHit == "Untagged"){
script.canmove = true;
break;
}
if (ObjectHit == "Enemy");
target = hit.collider.gameObject;
}
}
}
Instantiate(FireBallPrefab,transform.position,Quaternion.identity);
}
It's activated when the "q" button in pressed. I'll list the useful local variables here:
var script = gameObject.GetComponent(Movement);
var FireBallPrefab : GameObject;
var target : GameObject;
var ObjectHit : String;
Answer by Lovrenc · Aug 18, 2013 at 07:26 PM
Unity doesent crash, you created infinite loop! Your "while" never exits, it just goes on and on and on.
If your AutoHit doesent get target, it will search for it again and again... but nothing in your game really changed (you are searching same data every time!).
How to fix:
Change "while" to "if". If your AutoHit is suppose to find target every time it is called but it doesent, then something else in your code/game design is not working well.
============= EDIT =============
This is how code works.
Lets say you have:
Statement1
Statement2 <---- this is your while loop
Statement3
When you start this program, first Statement1 will fire, when done statemen2 will execute and at the end statement3. Now if you have an infinite loop, program will just stay at Statement2 as it never finnishes and Statement3 will also never execute, also program stops responding.
Therefore you HAVE to use IF. You need your game to progress!
Lets say you are looking for a mushroom in a forrest by a tree. Also, lets say time stopped. You can look by that tree for 100.000.000.000.000.000 times, if it wasnt there the first time, it wont be there any other time.
How to work around this than? Use unity events. Add your code in functions like Update or FixedUpdate.
var autoHitStarted: bool = false;
function AutoHit (){
autoHitStarted = true;
}
function Update() {
if(autoHitStarted) {
//Find your target
//if you found target, set autoHitStarted = false;
}
}
That's what I want though. I want that part of the script to continuously loop until it gets a target. If I use an "if" statement it won't loop. The data doesn't change until the user clicks, but the user can't click because it crashes. Hence why the target is changed to what the ray hits or the loop breaks.
If I am to understand correctly, the "while" statement freezes in that part of code until it can continue. This means I cannot cast rays inside while loops because the physics won't allow it?
No.
Of course physics allows it, and you are probably casting touzands of rays every second, but you locked the game. Game is not progressing. Time is stopped, nothing is moving, nothing is changing.
Also, this is not unity problem, this is pure lack of program$$anonymous$$g knowledge. Check this
You probably want your game to run at many hundreds of frames per second. This means that you can't spend any more than a few milliseconds in any given frame. Any code you write must complete quickly. Your while loop is furiously trying to do something . . . forever until it gets it right. If it never gets it right you won't exit & your game won't progress on to the next frame, and if it's running in your editor your editor will never get an opportunity to resume control.
Please understand that if this sounds mysterious to you you're simply starting at the wrong starting point, take some time to grow your software development skills & then dive in. Unity makes everything wonderfully simple but it can't substitute experience.
Incidentally, Lovrenc has answered your question, provided a solution and tried to explain the context to you. I've only done two of those things, in this forum it's appreciated if you mark one or both of our answers as accepted answers.
No no, I understand it now. I think I merely misspoke when saying "physics". I didn't mean the physics engine but more... physically it can't happen. I'll probably have the script run another script's update function.
Answer by weenchehawk · Aug 18, 2013 at 07:28 PM
I expect unity is not crashing, but instead Hanging. This may be because your script will execute forever in that loop while target is null.
Target only gets set when ObjectHit = Enemy. Depending on how quickly it takes to hit an enemy it will continue to execute for ever in this script. Now, in addition, your Physics simulator, main game loop, general game progression is paused because your frame does not progress until your loop exits, that's why unity seems to hang,
Would that still cause the editor to not respond? I press the play button again and it won't stop playing unless I close it in task manager. If this is the case however, I'm supposing the "while" event keeps it stuck in the same frame so it cannot cast the ray?
You do not understand. It is not the editor, that is not responding, you are essentially stopping your game.
While your game runs in the Editor they both share the same execution thread, if one gets caught in an infinite loop so does the other. Both Lovrenc & I have answered the question correctly, what you need to do is figure out how to make your code only do one iteration of a loop each time it is entered. Lovrenc's suggestion of using if ins$$anonymous$$d of while is a fine suggestion.