SirAfk
SirAfk

Reputation: 13

Physics2d.IgnoreLayerCollision not working when PlatformEffector2D is used

So I'm working on a basic platforming game, and my player controller has a system where if S is hit, then the player should ignore collisions with objects in the platform layer. However, Even though run the IgnoreLayerCollision, my player still detects the collisions. Any fixes?

private void FixedUpdate()
{

    //Drop through platforms or not?

    if (dropDown)
    {
        Physics2D.IgnoreLayerCollision(9, 8, true);

        playerCollider.enabled = false;
        platformCollider.enabled = false;
        playerCollider.enabled = true;
        platformCollider.enabled = true;

        print("Dropdown");
    }else
        Physics2D.IgnoreLayerCollision(9, 8, false);
}

void getInput()
{
    if(Input.GetKeyDown(KeyCode.S))
    {
        dropDown = true;

    }
    else if(Input.GetKeyUp(KeyCode.S))
    {
        dropDown = false;

    }

}

Dropdown does print properly

Platform inspector

player inspector

Layers

Inspector for platform

Inspector for player

Upvotes: 1

Views: 4269

Answers (3)

Thomas Nill
Thomas Nill

Reputation: 1

i solved this problem with: change by "Platform Effector 2D" the "Use Collider Mask" to false

Upvotes: 0

Programmer
Programmer

Reputation: 125415

The FixedUpdate function is called every fixed framerate frame. When dropDown is false, Physics2D.IgnoreLayerCollision(9, 8, false); is called every fixed framerate frame. I do think this is the problem. You need to call this once only. Similar thing happens when dropDown is true. Physics2D.IgnoreLayerCollision(9, 8, true); is called every fixed framerate frame but this should only be called once.

Move that code directly to your getInput function so that they are called once only. Ofcourse, you can use boolean variables in the FixedUpdate function to fix this but that's totally unnecessary.

void getInput()
{
    if(Input.GetKeyDown(KeyCode.S))
    {
        Physics2D.IgnoreLayerCollision(9, 8, true);

        playerCollider.enabled = false;
        platformCollider.enabled = false;
        playerCollider.enabled = true;
        platformCollider.enabled = true;
    }
    else if(Input.GetKeyUp(KeyCode.S))
    {
        Physics2D.IgnoreLayerCollision(9, 8, false);
    }
}

getInput must be called from the Update function. Finally, make sure that both objects are set to layer 8 and 9 in the Editor or code. It won't work if they are not set to these layers.


Using PlatformEffector2D with Physics2D:

With your new screenshot in your question, Physics2D.IgnoreLayerCollision is not currently working because you are using PlatformEffector2D on your colliders.

It doesn't work because PlatformEffector2D have it's own collider mask settings which is enabled by default and overrides whatever you set to Physics2D.IgnoreLayerCollision. You can use PlatformEffector.colliderMask to select the layers or disable PlatformEffector2D's mask so that you can use Physics2D.IgnoreLayerCollision. I suggest disabling PlatformEffector2D's mask as that's because it's more easy to use Physics2D.IgnoreLayerCollision.

You can disable PlatformEffector2D's mask by setting PlatformEffector2D.useColliderMask to false. This must be done for both the player and the platforms PlatformEffector2D component.

Just add to the Start function:

void Start()
{
    PlatformEffector2D playerEffector = playerCollider.GetComponent<PlatformEffector2D>();
    PlatformEffector2D platformEffector = platformCollider.GetComponent<PlatformEffector2D>();

    //Disable PlatformEffector2D
    playerEffector.useColliderMask = false;
    platformEffector.useColliderMask = false;
}

Also modified your title to reflect that you are using PlatformEffector2D.

Upvotes: 3

Patt Mehta
Patt Mehta

Reputation: 4204

Firstly, you should only use single key method (only use key-down) to toggle ignore-collision property of the 2 layers. This is demonstrated in below code, here layerCube is for yellow cube and layerRoof is for blue roof.

Try adding logs in your code to test your incorrect logic.

roof and cube image

public class Character : MonoBehaviour {
    bool ignore = false;
    int layerCube = 0;
    int layerRoof = 8;


    void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
            GetComponent<Rigidbody>().AddForce(Vector3.up * 8,ForceMode.Impulse);
        if (Input.GetKeyDown(KeyCode.S)) {
            ignore = !ignore;
            Physics.IgnoreLayerCollision(layerCube, layerRoof, ignore);
        }
    }
}

Secondly, the below snippets in your code are also completely wrong and should be corrected:

playerCollider.enabled = false;
platformCollider.enabled = false;
playerCollider.enabled = true;
platformCollider.enabled = true;

the above code effectively is simply setting the colliders to true. For what you are trying to achieve, you should simply remove the above lines. These are not at all required if you are already adding code to ignore layer collisions.

Upvotes: 0

Related Questions