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\$
  • \$\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 '14 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 '14 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 '14 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 '14 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 '14 at 17:09
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\$

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.