Question

I'm working on a 3D tile based game and I'm using AABB collision detection. For every cube that the player is intersecting, I find the axis along which the player is intersecting the cube the least, and push the player out of the cube along that axis.

Depending on the order that the cubes are checked in, this can cause problems when sliding along the edge of multiple cubes. I have created a diagram that should explain the problem:

http://imgur.com/mmK0W.png

  • Arrow #1 is the attempted movement of the player. The other arrows are the collision response.
  • In the left diagram, collision is tested against the right cube first, causing the player to be pushed to the left, and then upwards. (bad)
  • In the right diagram, collision is tested against the left cube first, causing the player to be pushed upwards, at which point the player is no longer intersecting the other cube. (good)

Any ideas on what the most efficient way to solve this might be? Or any better ways to handle the collision response?

Thank you.

Was it helpful?

Solution

A discrete implementation forces you to inject some continuous math in the system, only when required (cubes / directions overlap).

For each cube c1, c2 ... ci with which the user cube (uc) intersects at the time of the check, you want to find out which cube was "touched" first - there is only one, as in real life. Consider the direction d of uc, and, taking the amount of uc in ci (overlapping) find the position of cu at the time it "touched" ci.

Determine which cube was "touched" first cj (the one that required the most rollback on the d axis - the sooner in time) and use only this one to calculate the collision reaction.

Not only you'll reach accuracy. but it will help if all cubes are moving, have different speeds etc...

OTHER TIPS

From your diagram, it seems you want the smallest move that minimises the overlap between the player and the cubes. Each cube with overlap will try to "push" the player in two orthogonal directions. Can you do something like pick the minimum push of the maximum pushes in each direction?

You might implement a kind of hybrid broad phase when your two (or more) stationary cubes in a row can be combined into one larger rectangle. Test against the larger rectangle first. It will give you the results of your green check mark and be faster than checking each cube anyway. Then, after that, only if you need to, check against the individual cubes.

A collision can push an object on 1 axis only. To determine the axis to push:

else   -- not this
elseif -- change to this

if w > h then
    push x
elseif h > w then
    push y
end

This works if your tiles are aligned.

Use circles to avoid the stick on unaligned tiles

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top