For the life of me, I cannot figure out why this is not working. I have tried using Physics.IgnoreLayerCollision, and I have tried making an “Immortality” layer, went into the Physics preferences, ticked off the box between “Immortality” and “Enemy”, and scripted the character to switch to this layer after getting hit. I still cannot walk through the enemy. Someone please help me out here.
BTW, layer 9 is “Player”, layer 10 is “Enemy”, and layer 11 is “Immortality”.
using UnityEngine;
using System.Collections;
public class JabHealth : MonoBehaviour
{
public GameObject[] hearts;
private int health;
public bool immortality = false;
public float immortalTime = 2.0f;
public float origTimer = 2.0f;
// Use this for initialization
void Start ()
{
health = hearts.Length;
print (health);
}
// Update is called once per frame
void Update ()
{
ResetImmState (immortality);
}
void ResetImmState (bool resetTimer)
{
if (resetTimer)
{
immortalTime -= Time.deltaTime;
gameObject.layer = 11;
Physics.IgnoreLayerCollision(10, 11, true);
if (immortalTime <= 0)
{
immortality = false;
gameObject.layer = 9;
Physics.IgnoreLayerCollision(10, 11, false);
immortalTime = origTimer;
}
}
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.layer == 10)
{
health = health - 1;
hearts[health].SetActive (false);
immortality = true;
}
if (health == 0)
{
Application.LoadLevel (Application.loadedLevelName);
}
}
}
Well let’s work through the logic here.
“immortality” is initially set to false, every frame in Update, the “ResetImmState” function is called and “immortality” is passed in. Inside of the “ResetImmState” function, “immortality”, which now can be referenced as either “immortality” or “resetTimer”, is checked and found to be false, so it does nothing, once a frame, every frame.
At some point in the future, you run into an object in layer 10, reduce health, and set “immortality” to true. In the Update now, the “immortality” variable comes back as true, time is removed each frame from a 2 second countdown and the layer is changed to be 11, collisions between 10 and 11 are told to be ignored (all of this happening every single frame), and then finally once the countdown reaches 0, everything is reset.
Some tips:
- The “immortality” variable is class-wide and there’s no reason to pass it into a function as a parameter. Inside of "ResetImmState, it can see “immortality” just fine.
- When possible, use the Layer Collisions Matrix in the Physics options in Unity to permanently set layers to ignore eachother. If layer 11 is specifically made for ignoring collisions, it doesn’t really seem like that functionality needs to be dynamically enabled and disabled- just swap objects into that layer and back out of it when necessary.
- If you must use the IgnoreLayerCollisions function (which you probably shouldn’t), keep in mind that the Physics engine doesn’t really like you changing the rules on it dynamically like this, so perhaps disabling and then re-enabling the collider on the player object here after the change is made will give it the shock it needs to update to the new collision settings.
- There’s no need to do any of this every single frame. Look into Coroutines to get all of this functionality far more efficiently, and just call it from the OnCollisionEnter after the death-check. The Update function here can be removed entirely.
- Try to fit everything relevant to a topic (including additional questions you may come up with later) into the original post. There wasn’t anything new here, so it all could’ve been answered in the topic you already posted.
But I already went into the Layer Collision Matrix and disabled collisions between the Immortal and Enemy layers. I also checked the Inspector during runtime to confirm that the player does actually switch to the Immortal layer and stay there for the duration of the two seconds, and he does. So why is the collision not being ignored?

First, comment out the IgnoreCollisionLayer lines if they aren’t needed. Next, disable and enable the collider script for the player after the layer is changed, to see if that updates the collision detection. Finally, check to see if there are multiple colliders on either the player or enemy objects- this can happen if the GameObject has a rigidbody and a child with a collider, creating what’s called a compound collider. Compound colliders can have multiple layers (if one collider is on one layer and another is on a different one), which can interfere with these kinds of things.
2 Likes
I cannot thank you enough. Turns out there was a box collider on one of my character’s child objects. I changed it to layer 11 and now it works correctly. Again, thanks! And sorry for all the topics, my mind has just been all over the place tonight. Won’t happen again.