Multiple Collisions

Sorry if this is a really newbie question, but, I’m just that.

Anyways, I have a simple game created. The map is all in one camera view, and it’s just a black platformer kind of style (See pictures at the end). I then also have the player, which is a square, a couple spikes, and a finish flag at the top. My problem is trying to detect collisions for multiple things on my player. I don’t know what to do since you can’t have duplicate named functions (OnCollisionEnter2D is what im using.) So how would I say, “If you touch ground, you can jump. If you hit spike, you die.” Without using this method multiple times? Heres my code. You can probably see what im trying to do here. Can’t get left or right to work, and jumping isnt working because of the ground tag thing. That’s in another post however.

using UnityEngine;
using System.Collections;

public class Movement : MonoBehaviour
{

    public float speed = 5.0f;
    public float jumpHeight = 10.0f;
    public bool isDead;
    private Rigidbody2D myRigid;

    void Death ()
    {
        if (isDead == true)
        {
            Destroy (gameObject);
        }
    }

    void Start ()
    {
        myRigid = GetComponent<Rigidbody2D> ();
    }


    void Update ()
    {

 
        if (Input.GetKey (KeyCode.LeftArrow))
        {
            myRigid.velocity = new Vector2(-10,0) * speed * Time.deltaTime;
            Debug.Log ("I should be going left!");
        }

        else if (Input.GetKey (KeyCode.RightArrow))
        {
            myRigid.velocity = new Vector2(10,0) * speed * Time.deltaTime;
            Debug.Log ("I should be going right!");
        }

        if (Input.GetKey (KeyCode.Space))
        {
            //myRigid.velocity = Vector2.up * jumpHeight * Time.deltaTime;
            Invoke("OnCollision2D(Collision other))",1.0f);
            //Debug.Log ("I should be jumping!");
        }

    }

    // OnCOllisionStay2D for 2D box collision detection
    void OnCollisionStay2D(Collision2D col)
    {
        if (col.gameObject.tag == "Spike")
        {
            Death();
            Debug.Log ("I should be dead!");
        }
    }

    void OnCollision(Collision other)
    {
        if (other.gameObject.name == "Floor" && Input.GetKey(KeyCode.Space))
        {
            myRigid.velocity = Vector2.up * jumpHeight * Time.deltaTime;
            Debug.Log ("I should be jumping!");
        }
    }
}

EDIT: I found out what the problem was with the left and right movement lol. I feel stupid. But the tag thing is still hindering me from jumping and I dont know how to use that with multiple detection’s. First game. New struggles.

On the multiple collisions thing, why wouldn’t you just add another if block (or if/else)?

if (other.gameObject.CompareTag("spike"))
  // you die
else if (other.gameObject.CompareTag("floor"))
  // you jump
else if (other.gameObject.CompareTag("flag"))
  // you win

Then you just tag the objects and you can determine which code to execute based on the object that was hit.

Jay

Ohhhhhh my you just made me feel so stupid :smile: I have no idea why I was assuming that you could only have 1 if statement in a built in function… Lol. Thanks a lot!

However it’s still not wanting to jump tho? Is it still because of the code?

void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.tag == "Spike")
        {
            Death();
            Debug.Log ("I should be dead!");
        }

        else if (other.gameObject.name == "Floor" && Input.GetKey(KeyCode.Space))
        {
            myRigid.velocity = Vector2.up * jumpHeight * Time.deltaTime;
            Debug.Log ("I should be jumping!");
        }
    }

Not even getting the debug log

No problem – you did say you were a newbie. :wink:

I remember the first time I learned about file I/O (saving and loading data) – before that time I was just hardcoding data in variables, and when I discovered you could gasp! save data and load it back in!!!.. That was about 32 years ago, but I still remember that feeling. It was as if my whole world had just expanded into the infinity.

Jay

So that means either the object name isn’t Floor or the Input isn’t right. Add a Debug.Log line outside of the if block and print out the name of the object you’re hitting, that will help narrow down where the problem might be.

Jay

I ended up approaching it a different way.

[Error Fixed]

So my log tells me that I’m detecting the floor, and that I should be jumping. However it only logs that i’ve hit the spacebar one time.

I’ve narrowed it down to it not detecting that im hitting the spacebar. I am doing this properly right?

if (hasJumped == 0 && Input.GetKey (KeyCode.Space))
        {
            myRigid.AddForce(Vector2.up * jumpHeight * Time.deltaTime);
            hasJumped = 1;
            Debug.Log ("I should be jumping!");
            Debug.Log ("hasJumped is set to: " + hasJumped);
        }

Whole script so far:

using UnityEngine;
using System.Collections;

public class Movement : MonoBehaviour
{

    public float speed = 35.0f;
    public float jumpHeight = 10.0f;
    public int hasJumped = 0;
    public bool isDead;
    public float gravityScale = 6.0f;
    private Rigidbody2D myRigid;



    void Death ()
    {
        if (isDead == true)
        {
            Destroy (gameObject);
        }
    }

    void Start ()
    {
        myRigid = gameObject.GetComponent<Rigidbody2D>();
    }


    void Update ()
    {


        if (Input.GetKey (KeyCode.LeftArrow))
        {
            myRigid.velocity = new Vector2(-10,0) * speed * Time.deltaTime;
            Debug.Log ("I should be going left!");
        }

        else if (Input.GetKey (KeyCode.RightArrow))
        {
            myRigid.velocity = new Vector2(10,0) * speed * Time.deltaTime;
            Debug.Log ("I should be going right!");
        }

        if (hasJumped == 0 && Input.GetKey (KeyCode.Space))
        {
            myRigid.AddForce(Vector2.up * jumpHeight * Time.deltaTime);
            hasJumped = 1;
            Debug.Log ("I should be jumping!");
            Debug.Log ("hasJumped is set to: " + hasJumped);
        }


    }

    // OnCollisionEnter for 2D box collision detection
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.CompareTag("Spike"))
        {
            Death();
            Debug.Log ("I should be dead!");
        }

        else if (col.gameObject.CompareTag("Floor"))
        {
            hasJumped = 0;
            Debug.Log ("I am detecting the Floor...");
        }
    }


}

Here’s the log. Spamming space bar. Only reason why my “detecting floor…” is at a high number is because I’m detecting collision on anything considered “Floor”, which is the outline of the whole map lol. Later on ill have to just make an edge collider instead

2629858--184846--Pls.png

Try increasing the force to 10,000 to see what happens. If you go flying off the screen then start lowering the value until you get the jump height you want.

The log is showing that it has registered the space bar because the has jumped == 1 so you may not have enough force.

For your movement you’re setting your Velocity explicitly, which will cancel out any “AddForce” velocity you add for your jump. Make them all use AddForce so that all the forces are combined, not overwritten.

Like this:

myRigid.AddForce(Vector2.right * speed * Time.deltaTime);
//and
myRigid.AddForce(Vector2.left * speed * Time.deltaTime);

If you want the effect of instant-turning like a retro style control scheme, you can set your horizontal velocity to zero when you change direction like this:

// left key pressed

// if moving to the right with any speed
if(myRigid.velocity.x > 0){
    // negate the horizontal velocity
    Vector2 newVelocity = myRigid.velocity;
    newVelocity.x = 0;
    myRigid.velocity = newVelocity;
}

// then add the force
myRigid.AddForce(Vector2.left * speed * Time.deltaTIme);

You can do the same for right, but check for velocity.x is less than zero, and then use Vector2.right.

Also you should be doing physics changes in FixedUpdate, not Update.

1 Like