In games similar to my own, when the player gets hit they are temporarily invincible. While in this state, they can pass through enemies. I need to implement this in my game. I have the invincibility working, but the player is still blocked by enemies, and they can get pinned down and repeatedly hit by them.
But how can I make my player pass through enemies?
My first thought is to set my colliders to be triggers, but both my player and my enemies are using their colliders to not fall through world geometry, so I canât set them to be triggers.
My next thought is maybe disabling collision between layers, but I donât know how to instigate that on-the-fly via script.
And as I think about it, I probably just want the player to be able to pass through enemies all the time, because otherwise I could have problems if the collision get enabled while the player is inside the enemy. Although even if I used triggers Iâd run into issues in the same scenario because âOnTriggerEnterâ wonât get called if Iâm already touching the other object.
But, at any rate, any thoughts as to how I could handle this issue? How can I have my player pass through enemies while both still collide with the world, and can still register collisions with each other when the player isnât invincible?
I recommend using separate colliders for physics and collision detection. I use a trigger to detect when my player touches enemies, collectibles, checkpoints, etc. I use a separate non-trigger collider so my player does not pass through world objects. The best part of this approach is that I never need to enable/disable with the colliders/rigidbodies or mess with layers⌠if I want to disable collision with enemies, I can just have an âifâ check in my âOnTriggerâ functions before I run the code for colliding with enemies.
But if both the player and the enemies have colliders, wonât they still collide with each other? Even if you use a second collider for trigger collisions, the non-trigger collider will still contact the other characters who also have such colliders.
If youâre talking about physics collisions that prevent colliders from passing through each other, you can go to [Edit â Project Settings â Physics (or Physics2D)] and use the checkboxes to decide what layers can collide with what.
What I do is Iâll have a player parent object with a child object for player physics (rigidbody and non-trigger collider), and another child object for player triggers (trigger colliders, no rigidbody). I put the two on different layers. I disable the player physics from colliding with enemy physics using the physics menu so that they can always pass through each other. I enable player triggers from colliding with enemy triggers so that I can detect âOnTriggerâ functions without the two colliders pushing each other. I use a seperate class to detect triggers and report them to the player class. I use âifâ checks in the âOnTriggerâ functions so I donât call âTakeDamageâ functions if the player is invulnerable.
Huh, a child object can be on a different layer?
Most of the stuff I have tried to do with child object just frustrated me because everything was being compounded as if it were one massive trigger.
This process you describe sounds like it would be worth pursuing; I will look into it.
(That being said, if anyone has any other ideas, Iâm still willing to hear them. Always helpful to have another tool in your belt.)
Yes, child objects can have different layers. When you set the layer of a parent, Unity will ask âdo you want to set all of the children to the same layer?â
If you have a parent rigidbody with multiple child colliders, all of the colliders will be compounded into one massive collider, as you said. Multiple child colliders will only be combined if they have the same rigidbody somewhere above them in the hierarchy.
I got a little more free time and did some reading through the docs because I donât use Unity physics very often. It seems you actually can have all of your colliders (triggers or not) under the same parent. Anything marked âTriggerâ will call âOnTriggerâ functions and not physically collide, and anything not marked âTriggerâ will call âOnCollisionâ functions and will physically collide. You can check the tag of the object you collided with to decide which actions you should take, and you can use an âifâ check to skip those actions if youâre invulnerable.
I think this will be an easier approach because your rigidbody collider wonât separate from your trigger collider due to physics. The previous method I suggested will require you to sync collider positions through code.
I tried to implement this for a demo brick-breaker clone and it worked well. My brick gameobjects now have two children - one has a collider setup as a trigger and the other child without a trigger- i can make an object solid by only enabling the âphysicsâ collider and not solid by only enabling the âtriggerâ collider which is easily scriptable. I was struggling with how to implement this until i read the reply, kudos to MSplitz-PsychoK