Ignore Collision depending on Color

Hi, I am trying to “rebuild” some of there more famous concepts of other games / people to learn how things work. At the moment, I try to build something like this:

Platform at Start of Game: Color Grey
Player 1 jumps on it → Turns Blue
Player 2 jumps on it → Turns Pink

For Player 1, whenever the Platform is pink, the Collider is ignored and visa versa.

It works for the most part, however there is one issue.

If the Platform already is blue or pink and the player of the opposite color jumps on it, the platform does change it’s color and also ignores the collider after. As example:

Platform is blue. Pink player jumps on it.

What SHOULD happen is that the platform is completely ignored, as it’s blue.

What DOES happen is that it changes to pink and more or less at the same time, it is ignored.

That of course makes the platform non available for the blue player as well, but also for the pink player as the visual color is pink, but it seems to get processed as blue.

So the question is, how can I make the pink player ignore a blue platform completely?

I tried changing the collider of the player, but then again, the jump detection doesn’t work…here is my code, it’s probably bad but well I tried to not just copy everything :wink:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Platform : MonoBehaviour
{
    private Renderer rend;
    public Color blue;
    public Color pink;

    void Start()
    {
        rend = GetComponent<Renderer>();
    }

    public void OnCollisionEnter2D(Collision2D collision)
    {

        if (rend.material.color == pink && collision.gameObject.tag == "playerblue")
        {
            Physics2D.IgnoreLayerCollision(9, 10);
        }

        if (collision.gameObject.tag == "playerblue")
        {
            rend.material.color = blue;
        }

      

       

        if (rend.material.color == blue && collision.gameObject.tag == "playerpink")
        {
            Physics2D.IgnoreLayerCollision(9, 10);
        }

        if (collision.gameObject.tag == "playerpink")
        {
            rend.material.color = pink;
        }
    }
}

I also tried to add something like this:

if (collision.gameObject.tag == "playerblue" && rend.material.color != pink)

this works BUT

player blue jumps on it, all good
player pink jumps on it, ignores everything, doesnt change the color, all good

but somehow the collider gets deactivated(?) and the blue player cant jump on it anymore, despite it being blue…

Hello, I didn’t tried myself this but i have a guess :
Physics2D.IgnoreLayerCollision documentation: Choose whether to detect or ignore collisions between a specified pair of layers.

To me it seems that the IgnoreLayerCollision is not ignoring the particular collision you’re working on in your CollisionEnter but is settings the physics to ignore ALL collisions between layer 9 and 10.

So if your blue player is in one of those layers all collisions after youre pink player have hit the blue plateform involving also the blue player will be ignored

ahh yes of course :hushed: that worked I just had to add another layer lol - thanks!

a little minibug is that there is a splitsecond before the collider realizes it should disappear, so the player stans for a very short amount of time in the air (but only the first time it touches the platform, after that it’s normal)…if anyone has an idea here, let me know :sunglasses: (brackeys, where I stole that idea from uses another way I know that but I am trying this way to learn)

The issue here is that you cancel the collision when it’s computed, so it’s to late. You should ignore it from the start meaning :

In the physics settings ignore collisions between blue player layer and pink plateforms layer (and other way)
and when a plateform become blue for example assign it to blue plateform layer immediatly.
So this way when pink player will jump on it, the physics engin wont detect any collision

try something like this :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Platform : MonoBehaviour
{
    private SpriteRenderer rend;
    public Color blue;
    public Color pink;
    public LayerMask bluebox;
    public LayerMask pinkbox;

    public GameObject bluePlayer
    public GameObject pinkPlayer
    public void Start()
    {
        // This should be done only once doing it multiple times is useless (but i put here so you can see what i meant)
        Physics2D.IgnoreLayerCollision(bluebox, pinkPlayer.layer);
        Physics2D.IgnoreLayerCollision(pinkbox, bluePlayer.layer);
        // You can also remove these lines if you make the change in physics settings menu

        rend = GetComponent<SpriteRenderer>();
    }

    public void OnCollisionEnter2D(Collision2D collision)
    {
        // As we ignored collsions between player and box not the same color it leave us with only 2 cases
        // Either the box is grey or the same color of the player
        // if it's the same color, we don't have anything to do
        // so we need to do something only if it's a grey plateform

        if (collision.gameObject == bluePlayer && rend.material.color != blue)
        {
            this.gameObject.layer = bluebox;
            rend.material.color = blue;
        }
        if(collision.gameObject == pinkPlayer && rend.material.color != pink)
        {
            this.gameObject.layer = pinkbox;
            rend.material.color = pink;
        }
    }
}

Thanks a lot for your help, that is looking really like it should work and I actually learned something :slight_smile: - however I have two strange things happneing. I am trying to get my head around it (and tried all I came up with), but if you are willing to help me that of course is appreciated :sunglasses:

so first, the player sadly do not ignore the collision if wrong color. second, I get the error "a game object can only be in one layer. the layer needs to be in range (0…31). I have googled this, but I checked and cant see where I am missing something or where I dublicate a layer…only maybe the 2 layermasks?

well here everything how I set it up, maybe there is something very obvious…

got it - if anyone needs, code attached - thanks again you were really helpful :slight_smile:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Platform : MonoBehaviour
{
    private SpriteRenderer rend;
    public Color blue;
    public Color pink;
    public LayerMask bluebox;
    public LayerMask pinkbox;

    public GameObject bluePlayer;
    public GameObject pinkPlayer;
        public void Start()
    {
        rend = GetComponent<SpriteRenderer>();
    }

    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject == bluePlayer && rend.material.color != blue)
        {
            gameObject.layer = 11;
            rend.material.color = blue;
        }
        if (collision.gameObject == pinkPlayer && rend.material.color != pink)
        {
            gameObject.layer = 12;
            rend.material.color = pink;
        }
    }
}