5
\$\begingroup\$

What is the most accurate way to find the correct position to where a moving character should be re-positioned as a collision-resolution, after it has collided with multiple colliders?

The figure below illustrates the situation. The rectangles in black are the walls, the rectangle/circle in blue is the moving character and the arrow in read shows the direction of movement, i.e. in this case from right to left. My set up is in 2D and I am using C# in Unity.

enter image description here

\$\endgroup\$
1
\$\begingroup\$

I encountered a similar problem in a game of mine when defining collision physics for grenades my character throws. I found a solution that could fit your needs.

When an object (e.g. a ball) moves along its trajectory, whether or not affected by gravity, it moves from point A to point B every frame (depending on the framerate you wish, you have to deal with delta timing), giving us a hint about its velocity. If no collision occurs when moving from A to B, we just place our ball in its new position, according to kinematics (first case in the image).

enter image description here

If at least one collision is detected, we find a position C (we don't mind if it's a 2D or 3D model - it works the same) which is the ultimate position along vector AB where our ball doesn't collide with anything else. Though, there's a small distance missing because our ball shall travel AB distance but actually it did AC, that is smaller (second case in the image). Then we calculate two values: the remaining distance (CB = AB - AC, you just apply Phythagoras' theorem when working with x and y values) and the new direction our ball shall move towards.

If motion from A to B is computed by a script (case 1), iterating it first on AC and then on CB (figure 2) will make the ball still travel AB distance, this time according to collision detection. Having more collision points for the same path shouldn't be a big deal, we just iterate our moving script three, four, five times as we need. You can make an iterative or recursive version of this algorithm.

In my personal project, I use an iterative script which does the following operations in order:

  1. If AB > 0, check collisions between A and B
  2. If no collision is detected, move object in position B
  3. If collision is detected, find point C and move object in point C
  4. Calculate distance CB and new direction angle (subscript for this one)
  5. Go back to 1 using new distance and new direction angle

Hope that helps.

EDIT: If your object DOES collide with two distinguished object at the same time, get the new direction angle as vector sum of the two hypotetical angles you would compute.

\$\endgroup\$
  • \$\begingroup\$ Hi, many thanks for your detailed answer. So, my problem is similar to what you have detailed (and showed in the picture). However, as described in my question, my situation is indeed of multiple walls being collided with at the same time. You mention in your last lines that it should be the case of summing the "hypothetical angles", but I am confused exact at this part. Could you elaborate a little bit on what you mean by that? In the case of my pictures, the moving char should probably be pushed back, but the trouble is precisely to know the exact position due to the dual collision. \$\endgroup\$ – Louis15 Nov 14 '15 at 4:06
  • \$\begingroup\$ In the case of the moving char that is a circle, it may be easy: I though of just finding the normals of each point touched in each wall and then finding the intersection point between these two normals. However, that does not work at all for the moving char that is a square (or arbitrary shape). \$\endgroup\$ – Louis15 Nov 14 '15 at 4:08
  • \$\begingroup\$ I'm assuming the circle (your fig.2) was moving left before collision occured, and that black rectangles are static blocks.If your circle simultaneously collides with both the blocks, we could compute the final direction of the ball (as a vector) if the other block wouldn't be there, for every block. This way we get two vectors, one pointing top-right and the other one pointing bottom-right: when summing them, we get a vector pointing right, as expected the ball collides and starts moving the other way. \$\endgroup\$ – liggiorgio Nov 16 '15 at 22:42
  • \$\begingroup\$ Exactly, but does that also work for figure 1, when the moving char is a square? I ask that because with the exception of the case of a circle, there is no symmetry between distance of the contact point and the center of the char \$\endgroup\$ – Louis15 Nov 17 '15 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.