Search code examples
unity-game-enginecollision-detectioncollider

Detect Collisions with Three Objects


I have a block that I'm moving around the level, and I want to make it so that if it hits a corner (ex: top right boundary), it doesn't move anywhere. Regular collision detection doesn't work, because I'm having the block move in short jumps (player.transform.position.x - 1, etc).

Here is the code I'm using:

public void OnCollisionEnter2D(Collision2D collision)
{ if (collision.gameObject.tag == "barrier" && (GetComponent<BoxCollider2D>().tag == "top" && GetComponent<BoxCollider2D>().tag == "left"))
    {
        player.canMoveUp = false;
        player.canMoveDown = true;
        player.canMoveLeft = false;
        player.canMoveRight = true;
    }
    else if (collision.gameObject.tag == "barrier" && (GetComponent<BoxCollider2D>().tag == "top" && GetComponent<BoxCollider2D>().tag == "right"))
    {
        player.canMoveUp = false;
        player.canMoveDown = true;
        player.canMoveLeft = true;
        player.canMoveRight = false;
    }
    else if (collision.gameObject.tag == "barrier" && (GetComponent<BoxCollider2D>().tag == "bottom" && GetComponent<BoxCollider2D>().tag == "left"))
    {
        player.canMoveUp = true;
        player.canMoveDown = false;
        player.canMoveLeft = false;
        player.canMoveRight = true;
    }
    else if (collision.gameObject.tag == "barrier" && (GetComponent<BoxCollider2D>().tag == "bottom" && GetComponent<BoxCollider2D>().tag == "right"))
    {
        player.canMoveUp = true;
        player.canMoveDown = false;
        player.canMoveLeft = true;
        player.canMoveRight = false;
    }
}

public void OnCollisionExit2D(Collision2D collision)
{
    Debug.Log("notTouching");
    player.canMoveUp = true;
    player.canMoveDown = true;
    player.canMoveLeft = true;
    player.canMoveRight = true;
}

EDIT: New code.

 if (Input.GetKeyUp(KeyCode.LeftArrow))
    {
        Vector2 movementLeft = new Vector2(-1, 0);
        RaycastHit2D hitLeft = Physics2D.Raycast(transform.position, movementLeft, -1);

        if (hitLeft.collider && hitLeft.collider.gameObject.tag == "barrier")
        {
            Debug.Log("N/A");
        }
        else
        {
            player.transform.position += new Vector3(movementLeft.x,movementLeft.y,0);
        }
    }
    else if (Input.GetKeyUp(KeyCode.RightArrow))
    {
        Vector2 movementRight = new Vector2(1, 0);
        RaycastHit2D hitRight = Physics2D.Raycast(transform.position, movementRight, 1);

        if (hitRight.collider && hitRight.collider.gameObject.tag == "barrier")
        {
            Debug.Log("N/A");
        }
        else
        {
            player.transform.position += new Vector3(movementRight.x, movementRight.y, 0);
        }
    }
    else if (Input.GetKeyUp(KeyCode.DownArrow))
    {
        Vector2 movementDown = new Vector2(0, -1);
        RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, -1);

        if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
        {
            Debug.Log("N/A");
        }
        else
        {
            player.transform.position += new Vector3(movementDown.x, movementDown.y, 0);
        }
    }
    else if (Input.GetKeyUp(KeyCode.UpArrow))
    {
        Vector2 movementUp = new Vector2(0, 1);
        RaycastHit2D hitUp = Physics2D.Raycast(transform.position, movementUp, 1);

        if (hitUp.collider && hitUp.collider.gameObject.tag == "barrier")
        {
            Debug.Log("N/A");
        }
        else
        {
            player.transform.position += new Vector3(movementUp.x, movementUp.y, 0);
        }
    }
    else
    {
        Debug.Log("N/A");
    }

Solution

  • A more simpler solution would be to use Physics.Raycast2D to check if theres any block in the way of your movement before moving it.

    This is rough idea of the code:

    // Some code to get input and end up with a movement vector
    ...
    movement = new Vector2(1, 0);
    
    // Raycast in the direction of movement with a distance of 1.
    RaycastHit2D hit = Physics2D.Raycast(transform.position, movement, 1);
    
    // We hit something and its a barrier
    if (hit.collider && hit.collider.gameobject.tag == "barrier")
    {
        // Don't move, play sound that indicate you hit a barrier or some sort
    }
    else
    {
        // Move to the new position
        transform.position += new Vector3(movement.x, movement.y, 0);
    }