Physics.IgnoreCollision doesn't work as the manual?

Hi,
In the manual it says:
Note that IgnoreCollision will reset the trigger state of affected colliders, so you might receive OnTriggerExit and OnTriggerEnter messages in response to calling this.

I want to make the player use a special skill, which will ignore the collision with the enemy in range when the player is not grounded or the enemy is not grounded. The collision should come back when they are both grounded.

So I can’t put the player and enemies into different physics layers for the logic only affects enemy in range when the skill is being used by player.

However, when I use Physics.IgnoreCollision to ignore the collision, I don’t receive any OnTriggerExit or OnTriggerEnter or OnTriggerStay event as the manual says. So I cannot reset the collision when the player and enemy are both grounded. They just do not collide, forever!

Does anyone know how to solve the problem? Thanks!

Physics.IgnoreCollision has an optional parameter ignore:

public static void IgnoreCollision(Collider collider1, Collider collider2, bool ignore = true);

which means after you’re finished with your skill, you should call it again with the ignore set to false.

Thank you for your reply!

Yes, I just want to use that to reset the collision. However, the collision reset should also be done when the skill is not finished (it’s a continuing skill). Each time I ignore the collision, I add the enemy to a list, and I should check all the enemies in the list to find they are grounded or not in each Update. It costs a lot if many gameobjects use GetComponent in each frame.

If OnTriggerExit can be used, it will be good news for performance, for I only need to deal with the enemies which are inside the trigger. Once an enemy is outside the trigger, the collision is reset. Then it’s removed from the list and is no longer processed in the Update.

It’s really hard for me to deduce what is it you’re trying to achieve here.

What manual states (if I understand it correctly) is that:

  • If objects are under collision (OnTriggerEnter was called at some point) and we use the IgnoreCollision, OnTriggerExit will be called due to objects no longer colliding (as we turned off the collision)
  • If objects are marked to ignore collision between them (IgnoreCollision with ignore set to true was called at some point) and we use the IgnoreCollision with ignore set to false, OnTriggerEnter will be called if they were to collide at the time of calling IgnoreCollision

Since you add enemies to the list, you can instead add a type which you are retrieving through GetComponent

So what you mean is: when player and an enemy are colliding with each other (OnTriggerEnter was called) and you call the IgnoreCollision, OnTriggerExit is not being called?

Thank you for your kind reply! Maybe I explained much more than the main question thus making the question hard to understand… It’s my fault.

Yes, that’s the main point. The enemy and the player both have a collider (IsTrigger not enabled), and I used Physics.IgnoreCollision. The manual says if I use Physics.IgnoreCollision, the collision between the two objects will fire OnTriggerEnter and OnTriggerExit event, but actually they don’t. It’s so confusing:(

If it’s not enabled, then those callbacks cannot possibly fire. In that case OnCollisionEnter and OnCollisionExit should fire, although I didn’t test it myself.

Thanks!
If two objects collide with each other, IsTrigger should not be enabled, otherwise the collision won’t happen.
The manual says Physics.IgnoreCollision will reset the trigger state of the collider, thus OnTriggerEnter and OnTriggerExit will be fired:
https://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html

So I’ve just tested it, and as expected, if IsTrigger is set to false, then ignoring and unignoring collision fire OnCollisionEnter and OnCollisionExit - not OnTriggerEnter and OnTriggerExit.

Manual is very misleading here because it doesn’t list functions by their flag which are:
OnCollisionEnter, OnCollisionExit when IsTrigger = false
OnTriggerEnter, OnTriggerExit when IsTrigger = true

This describes the behaviour when the collider is already using those events, ie IsTrigger is enabled when IgnoreCollision is called. You won’t get further OnTrigger events, just maybe some from the moment IgnoreCollision is called and the trigger state is reset.

I read your requirements as:

If (player.SkillActive && !player.IsGrounded && !enemy.IsGrounded && enemy.InRange) { //ignore collision }

Personally I’d be doing experiments with moving the enemies to another layer when appropriate (!enemy.IsGrounded && enemy.InRange) and setting IgnoreLayerCollision between the player layer and that layer from the player ground detection (player.SkillActive && !player.IsGrounded). I’m fairly new to Unity though so maybe someone has a better approach?

Thanks!
The result is just the same as mine. Maybe the manual is from old version and is not updated. However, I think I should try something else to make it work. Thank you so much for it takes you so much time!

1 Like

I guess the manual is misleading or is not updated to the newest version. Maybe try another way is a better choice for me.:frowning:

It’s a good approach to solve similar collision problems and I’m using it in other parts of my game too.:slight_smile:
However, Unity cannot create more than 32 physics layers, so maybe it’s not worth it to add specific layer for such a specific situation.

Thank you for your reply!

I was thinking of a generic layer like IgnorePlayer rather than EnemyIgnorePlayer, but yeah it needs planning and testing to fit the layer limits with all uses. Maybe moving all out of range enemies to the IgnorePlayer layer gives a performance boost and means my earlier logic needs reversing to enable player collisions instead of disabling them. Wish I could offer more than theory and ideas but I’ve not got to the experimentation stage on this stuff yet, I’m still researching and planning :slight_smile: