0
\$\begingroup\$

I would like to know how can I do one way collision. It's the collision common in mario's games and many platforms. I try to do an code but I cannot post because it's part of a paid game. Basically I have two rectangles like this:

struct Rect {
  int x, y; // positions in the world
  int w, h; // width and height
};

The rect A moves and the rect B is fixed with the world. Someone has a idea of how to do this?

\$\endgroup\$
5
  • \$\begingroup\$ Just to check if i have the question right, you are asking how to check for a collision between an actor and a static object once and not check collisions between the static object and the actor? \$\endgroup\$
    – Niels
    Feb 25, 2016 at 13:40
  • \$\begingroup\$ @user2645227 I think samleo is asking about the effect in platformers, where the character can jump through a platform from the bottom, but will collide and land on it when falling downward. Samleo, adding more descriptions or images to your question will help avoid ambiguity for future readers. As game developers we tend to lean pretty heavily on shared jargon, which can lead to a lot of confusion when we don't all have the same definition in mind... ;) \$\endgroup\$
    – DMGregory
    Feb 25, 2016 at 13:55
  • 1
    \$\begingroup\$ Requisite reading: higherorderfun.com/blog/2012/05/20/… \$\endgroup\$ Feb 25, 2016 at 23:31
  • \$\begingroup\$ So the problem is (simplified) if(Actor.bottom > obstacle.top){check collision} else{do nothing}? \$\endgroup\$
    – Niels
    Feb 26, 2016 at 6:53
  • \$\begingroup\$ Kinda, instead of checking the position; check the direction of movement: If the actor is moving up, do not check collision. If the actor is moving down: check for collision. \$\endgroup\$
    – Felsir
    Aug 6, 2016 at 14:22

4 Answers 4

1
\$\begingroup\$

Assuming that you have functional 2-way collision, all you need to do is check that the bottom of Rect A is above the surface of Rect B, and that the y velocity of Rect A is negative/down. Roughly:

void OnCollide(a, b)
{
    if(a.y - a.h * .5 > b.y + .5 * b.h && a.yvel < 0)
    {
        // do collide
    }
    else
    {
       // pass through
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Almost there, I tried to do this before and a I had a bad effect when the player's rect go from horizontal and so the collision is processed subtle. Any other idea? \$\endgroup\$
    – samleo
    Feb 25, 2016 at 13:34
  • \$\begingroup\$ What do you mean the collision is processed subtle? Can you rephrase? \$\endgroup\$
    – Nox
    Feb 25, 2016 at 14:11
  • \$\begingroup\$ For example, when the player goes to up side suddenly (was this word hehehe), like a teleport to up side. \$\endgroup\$
    – samleo
    Feb 25, 2016 at 17:04
0
\$\begingroup\$

You can use a Platform Effector on the game object that has the collider:

enter image description here

This provides a One-Way collision detection for platforms.

http://docs.unity3d.com/Manual/class-PlatformEffector2D.html

\$\endgroup\$
3
  • 2
    \$\begingroup\$ I think OP never mentioned that he is working with Unity :| \$\endgroup\$ Feb 25, 2016 at 13:25
  • \$\begingroup\$ I do this all the time. I'll leave it here in case Unity users are looking, lol. \$\endgroup\$
    – jgallant
    Feb 25, 2016 at 13:26
  • \$\begingroup\$ Well, I'm not using unity, sorry for this. I would like to know how to do this "in nature", just code from scratch, can you help me? \$\endgroup\$
    – samleo
    Feb 25, 2016 at 13:26
0
\$\begingroup\$

A solution may consist in deactivating all fixed colliders above your character and activating the ones under your character

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ It's this way that I use. But, I hold a vector of platforms without collision while player jumping or even when vel.y < 0. The problem is when the player go trough platforms it came from the sides, like in your image. I don't know when is the right moment of de/active the collision. Thank you for the help. I will try another approach. \$\endgroup\$
    – samleo
    Feb 25, 2016 at 17:02
  • \$\begingroup\$ This method doesn't scale well to multiplayer games, where one player could be above a platform and another player below it, or situations where AI characters need to be able to jump through platforms from below the way the player does. \$\endgroup\$
    – DMGregory
    Feb 25, 2016 at 19:59
  • \$\begingroup\$ This sort of deactivation only works properly in all cases if you're tracking each pair of contacts. e.g., once you collide, record the pair of collided objects. When they are no longer colliding, remove the record. This record can then store flags like "ignored" which disables the resolution code for that pair of objects, which you set from the collision callback if the player hits a platform from below, or if the player presses the "drop down" button, or whatever. \$\endgroup\$ Feb 25, 2016 at 23:34
0
\$\begingroup\$

I solved the problem. I just deactivate the collision detection in axis X and hold the detection in axis Y. Thank you people.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .