0
\$\begingroup\$

I've seen similar questions to this here on Stack Exchange — Game Development, but none of the answers to them have helped my problem. I am working in Unity 2019.2.18f1 with Visual Studios 2019 Community.

What I want to know how to tell when one Gameobject (the player) is currently touching another game object with a tag name of "Block". When the player collides with a "block" I want it to set: jumpPossible = true; But when it leaves the block (by jumping or falling off) jumpPossible = false;

What I currently have in my PlayerController script (the important stuff anyways):

private void OnCollisionEnter(Collision collision) {
    if (collision.gameObject.CompareTag("Block")) {
        jumpPossible = true;
    }
}

private void OnCollisionExit(Collision collision) {
    if (collision.gameObject.CompareTag("Block")) {
        jumpPossible = false;
    }
}

The problem I am having is when the player is currently on a block and then touches another block. When it leaves the one of the blocks, it will set: jumpPossible = false; and so you can't jump.

What I want for this script to do is whenever the player is touching any Gameobject with a tag of "Block" it should allow it to jump.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ We call this type of code a "ground check" and we have lots of existing Q&A about it. Usually it's solved not with tags and contact events, but with physics layers and ray/shape casts. \$\endgroup\$
    – DMGregory
    Commented Mar 31, 2020 at 21:14
  • \$\begingroup\$ Rigidbody2D has that handy method GetContacts, but unfortunately the 3d Rigidbody seems to miss that feature. \$\endgroup\$
    – Philipp
    Commented Apr 4, 2020 at 12:11
  • \$\begingroup\$ @Philipp you can get the contacts in the collision parameter of the OnCollision*() methods \$\endgroup\$
    – Max Play
    Commented Apr 4, 2020 at 12:14
  • \$\begingroup\$ @MaxPlay But that won't get you all the contacts the rigidbody is colliding with right now. Only those which relate to the collision between the two colliders which triggered the method call. If the rigidbody also touches some other colliders right now, you won't find those there. \$\endgroup\$
    – Philipp
    Commented Apr 4, 2020 at 12:15

1 Answer 1

1
\$\begingroup\$

To solve this particular problem, I would store a reference to the objects in a list, instead of setting a variable. In this case, I am using a HashSet, because it is faster than using a list, can only contain each entry once and we do not want to access the objects inside.

private HashSet<GameObject> touchingObjects = new HashSet<GameObject>();

public bool CanJump => touchingObjects.Count > 0;

private void OnCollisionEnter(Collision collision) {
    if (collision.gameObject.CompareTag("Block")) {
        touchingObjects.Add(collision.gameObject);
    }
}

private void OnCollisionExit(Collision collision) {
    if (collision.gameObject.CompareTag("Block")) {
        touchingObjects.Remove(collision.gameObject);
    }
}

Aside from that: Look into the link DMGregory provided. It could have better approaches to the problem that you are facing.

\$\endgroup\$
0

You must log in to answer this question.