2D collision Pipes to act like 3d (channels / layers)

edited in Questions and Answers
So I'm trying my hand at Unity, but have a bit of an issue with collisions in a 2D game

I have a game where I want to move an object along a channel ( see pictures attached).

I have split the images into 3 parts. The Red channel, The blue Channel, and the outside (white area). I am able to add colliders to all, and using tags or layers I can get a red token to move through the red channel only and blue token through blue channel only. My problem comes when the channels cross. I want for example the red token to be able to move through the red channel, and ignore the blue channel as long as it stays in the channel (otherwise the token could move into the red and exit via the blue which is not what I want)

Is this possible in 2d? or do I have to go 3d to be able to achieve this?

My current code looks like this:

void OnCollisionEnter2D(Collision2D collision)
 {
   if (collision.gameObject.tag == gameObject.tag)
   {
     Physics2D.IgnoreCollision(collision.collider, 
     gameObject.GetComponent<Collider2D>();
   }
 }

I have also tried adding a flag to indicate that the object is inside the channel, but this didn't work. I think this is probably a good approach, but can't get it to work right

void OnCollisionEnter2D(Collision2D collision)
     {
       if (collision.gameObject.tag == gameObject.tag)
       {
         inside = true;
         Physics2D.IgnoreCollision(collision.collider, 
         gameObject.GetComponent<Collider2D>();
       }
       if (inside)
       {
         Physics2D.IgnoreCollision(collision.collider, gameObject.GetComponent<Collider2D>();
       }
     }
 
   void OnCollisionExit2D(Collider2D collision)
   {
     if (collision.gameObject.tag == gameObject.tag)
     {
         inside = false;
     }
   }

imageimage

Comments

  • Can you attach those images you mention? :)
  • In case it helps, in your Physics settings (Edit > Project Settings > Physics 2D) at the bottom, there should be a grid of interactions for which layers collide with which other layers. You might be able to juggle around which obstacles and tokens are on which layers to allow some tokens to move through obstacles that others can't.
  • Krummelz said:
    Can you attach those images you mention? :)
    Sorry I thought I attached them. Updated the post
    In case it helps, in your Physics settings (Edit > Project Settings > Physics 2D) at the bottom, there should be a grid of interactions for which layers collide with which other layers. You might be able to juggle around which obstacles and tokens are on which layers to allow some tokens to move through obstacles that others can't.
    Yeah I've tried layers. They work very similar to tags, but maybe there is something I can work around. Power was off last night so couldn't work on it more.
  • Surround the Red Channel with a collider using a layer, lets call it RedLayer. Surround the Blue channel with a collider using a layer, lets call it BlueLayer.

    Then, set the blue token to also be on the BlueLayer, and the red token to RedLayer, and set up layer collision matrix so that blue and red don't intersect. If you need to, you can even add a specific layer for BlueToken and RedToken, and set up the layer collision matrix so that there are only collisions between the Red/BlueToken and Red/BlueLayer layers.
  • Ok, so I got this working (mostly)
    I am under NDA, but will still try to explain as clearly as I can.
    So the requirements are as follows (Not everything was in the original post)
    -There are 4 different channels (each with their own colours)
    -There are 4 different tokens (colours as above)
    -The token enters from outside the channel and exits outside again on the other end
    -Tokens must be dragged through the channel (i.e. I can't just teleport it to the other side when it enters)
    - A token may only move through a channel that shares it colour
    -Channels can cross over each other.
    -The whole board can be rotated (rotating all channels within it)

    The biggest problem I had was that Once a token enters a channel, and ignore the colliders of the other channel, it could then slip into the other channel where they cross. I tried to contain the tokens by using a distance formula, but it wasn't working.

    What worked: Layers was the right way to go, but I had to do some extra work. So I had the board (white part) with it's own collisions (polygon 2D) that nothing could go through.
    Then for each channel I would have the image of the channel (with no collisions) and nested under it I would have 2 more images: One with only the entry and exits lines (lets call it ImgEntry), and one with only the walls on the inside (lets call it ImgWalls). Both of these nested images had a polygon2d collider.
    Now I would make 3 layers for each colour.
    -TokenRed - for the red tokens
    -WallRed - for the red wall (ImgWall)
    -EntryRed for the entry lines (ImgEntry)
    Now in the layer collision matrix I would do the following for each colour.
    -TokenRed will ignore EntryRed (but collide with any other colour's Entry)
    -TokenRed will collide with WallRed, but Ignore collisions with any other colour's walls.

    This works great, but now there is another requirement. There is a black token, that can move through any channel, but again it is not allowed to switch channels mid-way through, so simple layer collisions will not work.
    I haven't implemented this yet, but I think my solution will be to have it collide with all layers. If it collides with EntryRed, disable collisions with that layer, and all Wall layers except red. When it hits any Entry collider though, I will first have to reset all the layer collisions, otherwise after a few time passing through different channels it will again be able to switch mid way through. There will also be a black channel, which will follow a similar rule, but will probably be implemented in much the same way.

    I think this works pretty well, and is about as elegant as I can think of. Other than having 3 images to make up one channel, I think it is pretty smooth.

    Thanks for the suggestions.
  • edited
    I would use a raycast in direction you are trying to move token to see if it may move there, rather than relying on collision events.

    The channels would consists of colliders on the edges. For example, the red channel would have a collider above and below and the blue would have to left and right (whatever you need to define the edge and they should cross). These colliders would be on layers indicating what channel they belong to.

    Using some variable (int) attached to token you keep track of what layer that token may not move through. For the black one you simply set the variable once the token enters a channel - maybe have a trigger at the entrance of each so you can detect this crossing into the channel via your raycast.

    Anyway, now your raycast can ignore all layers except the channel it belongs in so that it can move through overlapping channels since their "walls" are ignored. https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
Sign In or Register to comment.