Montag, 16. Mai 2016

6 Things that make Your Box2D world freeze

Ever encountered problems with your Box2D setup freezing or locking up and you don't know why?


Yes?

Then read on!

There are quite a few things you can do wrong with Box2D. I have collected a few common mistakes here. These mistakes include...


1) ... Changing the position of a body manually!
Generally, it's a bad idea to modify any body information directly, e.g. by using Body.setTransform() or changing position with Body.getPosition().set(x,y). This makes all contacts currently processed by the simulation invalid and ocreates unpredictable behavior.

Solution: Applying changes to velocity or position (including setting transformation) should always happen after the world has stepped. To do this, you can create a list of operations that is then processed after the world step. This can look a bit like this:
      
   world.step(...);
   if (!operations.isEmpty() )
   {
     operations.perform();
   }

See stackoverflow for more of this issue. You can also try copying the vector to avoid modifying it when using vector math.


2) ... Destroying physic bodies during a callback!
Raycasts and Queues are solved during a timestep. Modifying bodies during that process will cause Box2D to crash. Do not ever do this!

Solution: The code setup in 1) can help you out here. Send your destroy operations to a list containing bodies to be destroyed, where it is processed after the world has stepped. I do this in my game and it works perfectly fine.


3) ... Vectors getting NaN as values!
This happens if you apply an enormous amount of angular or linear impulses to your physic bodies, to the point they get catapulted to nowhere, because they adopt infinite velocity (and thus position).

Solution: Check your formulas and make sure the values are usable! It's a good idea to include a check on whether your values are valid when doing calculations; and throwing an error in case they don't.


4) ... References to destroyed physic bodies!
Once you have destroyed a body, it should not be referenced anywhere again.

Solution: Once destroyed, a body reference should always be set to null!


5) ... Creating physic bodies when the world is in the middle of a time step!
Because if you do, granted, you will get a freeze! This has caused me a lot of headaches personally.

Solution: You can use a similar solution as in 1): creating your objects after the world has stepped by putting them in your operations queue. 


6) ... Creating physic bodies that are created inside other physic bodies!
This causes your created physic bodies to be slung away like a bowl of peanuts gone crazy - if it doesn't crash first! In my experience, this happens when you have shooting mechanics, but the spawned projectiles touch the entity they were shot from.

Solution: There are numerous ways to solve this. You can either make sure your bodies are small enough and far away enough from a defined projectile spawning point - or if collision behavior doesn't matter too much, you can use collision groups and masking to avoid them touching each other.



I hope this helped you with any issues you had! If you still have problems, let me know - I'll be happy to help you out.

Keine Kommentare:

Kommentar veröffentlichen