3
\$\begingroup\$

I'm sure this is down to my lack of understanding of the unity physics system.

I'm trying to implement a simple one-way platform for a 2d game and have got stuck on creating a reliable way to let the character 'drop down' from a platform on pressing the down arrow.

While trying to debug and whittle down the code, I've found myself with this strange debug script:

using UnityEngine;
using System.Collections;

public class DebugPlatform : MonoBehaviour 
{

    void OnCollisionEnter2D(Collision2D other)
    {
        if(Physics2D.GetIgnoreLayerCollision (other.collider.gameObject.layer, this.gameObject.layer))
            print ("ERROR: How does this happen?!!");
        else 
            print("This is normal.");
     }
 }

When I place this on my one way platform and mess about in game, sometimes the character refuses to drop down on command, and the error message is printed.

From what I understood, GetIgnoreLayerCollision returned whether the collisions between the layers were being ignored or not.

So my questions are:

  • Why is OnCollisionEnter2D being called even though the layers are supposed to be ignored?
  • Is this ignore value just a request, not absolute? Maybe some collision optimization that I have to override?
  • I can't imagine this is some multi-threading issue, as the error appears regularly, after I do a normal jump on the platform.
  • Am I doing something completely wrong?

EDIT: Extra info: The one way platform is two parts, first an if else in FixedUpdate in the player script:

// Don't collide with platforms if flag is set or we are moving up:
if (ignorePlatform || transform.rigidbody2D.velocity.y > 0f)
    Physics2D.IgnoreLayerCollision (PlayerLayerID, PlatformLayerID, true);
else if(transform.rigidbody2D.velocity.y <= 0f)
    Physics2D.IgnoreLayerCollision (PlayerLayerID, PlatformLayerID, false);

The platform has an EdgeCollider2D on the top and a child with a Collider2D trigger underneath. A script then resets the player's ignorePlatform to false on exit. This is to make sure the player only falls through one platform when the down arrow is pressed.

\$\endgroup\$
5
  • \$\begingroup\$ How do you implement the one-way platform? Do you temporarily change collision layers? If yes, this could be the explanation. \$\endgroup\$
    – bummzack
    Oct 22, 2014 at 13:26
  • \$\begingroup\$ @bummzack I added some info about the one-way platform. I use Physics2D.IgnoreLayerCollision, I'm not quite sure what you mean by changing collision layers. \$\endgroup\$
    – mallardz
    Oct 22, 2014 at 13:56
  • \$\begingroup\$ Yeh I had issues with IgnoreLayerCollision too... It's like it slightly collides and seems jittery... Figure out another way to achieve what you want because I think the issue is the method itself. \$\endgroup\$
    – Savlon
    Oct 22, 2014 at 17:19
  • 1
    \$\begingroup\$ @Savlon That's really disappointing if it's just a bug, IgnoreLayerCollision seemed very useful. In the mean time I've followed your advice and reimplemented my one way platform. Now I use two colliders on the player character, one for normal collisions and one for the platform only. That way I can enable and disable the collider for the platform with the same code as before. \$\endgroup\$
    – mallardz
    Oct 23, 2014 at 18:58
  • \$\begingroup\$ Is it possible the player isn't through the edge collider before it gets turned back on? It seems to be getting un-ignored awfully quickly with transform.rigidbody2D.velocity.y <= 0f \$\endgroup\$
    – lase
    Dec 24, 2014 at 17:09

1 Answer 1

1
\$\begingroup\$

Unity 5 adds the PlatformEffector2D component, which I think solves this same question.

If you add a collider and attach it to this effector, you should be able to create the one-way platform with less fuss, which would simplify the code for dropping down, as well.

\$\endgroup\$

You must log in to answer this question.

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