To break the issue down, I have a player object split between a parent object with BoxCollider2D/Rigidbody2D and child CircleCollider2D trigger which acts as the attack hitbox for enemies. All scripts are on the parent.
I then have a boss object, the parent has a BoxCollider2D/Rigidbody2D that does not interact with the player (they are on layers that don’t interact). I then have a boss child object with a trigger that acts as the bosses hitbox (this is setup this way due to animations). All scripts but the animation script are on the parent.
The issue I am running into is that when the player attacks the boss (player child trigger overlapping the boss child trigger) the player takes damage as if the player parent collider touched the boss child trigger. Is their anyway to specify in OnTriggerEnter2D (on the player parent object) that it should only run that code if the player parent collider makes contact with the boss child trigger?
Thank you, but I have to admit I am still a bit stumped on how to check. I have tried specifying by tag (the player collider parent object is tagged 'Player" while the attack trigger child is tagged 'PlayerAttackCollider" with an if statement:
void OnTriggerEnter2D(Collider2D other)
{
if (gameObject.CompareTag("Player"))
{
if (other.gameObject.CompareTag("Boss"))
{
Debug.Log("ouch");
}
}
else if (gameObject.CompareTag("PlayerAttackCollider"))
{
if (other.gameObject.CompareTag("Boss"))
{
return;
}
}
}
I can’t disable the layer interactions because otherwise the boss can’t get hurt or it can’t hurt the player. Is there anyway to simply have this OntriggerEnter2D (which is in a script on the parent object) to ignore child triggers when checking if it should run the code? I apologize for the confusion.
Keep in mind what your shortcuts are. Line 3 and line 10 use the “gameObject” shortcut which is where this script is located. That may be reasonable, or it might not. If you have multiple of these scripts and they’re intended to live on various objects, that would make sense.
HOWEVER, if this script is supposed to be only on one entity and check for others, then you need to instead consider checking the GameObject of what you’re hitting.
This information is available in the other variable.
To see what I mean and reason about what is the right thing for you to do, try putting this in before line 3:
And run it and see what the names are. This is an awesome way to really find out what is going on. This is basic debugging and as you get better about it, you’ll get much quicker at learning how to figure out what is going on.
And obviously, you must find a way to get the information you need in order to reason about what the problem is.
What is often happening in these cases is one of the following:
the code you think is executing is not actually executing at all
the code is executing far EARLIER or LATER than you think
the code is executing far LESS OFTEN than you think
the code is executing far MORE OFTEN than you think
the code is executing on another GameObject than you think it is
you’re getting an error or warning and you haven’t noticed it in the console window
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run? what order does it run in?
what are the values of the variables involved? Are they initialized? Are the values reasonable?
are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)
Knowing this information will help you reason about the behavior you are seeing.
If your problem would benefit from in-scene or in-game visualization, consider using Debug.DrawRay() or Debug.DrawLine() to visualize things like raycasts or distances.
You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.
You could also just display various important quantities in UI Text elements to watch them change as you play the game.
If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.
Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.
Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:
Well, in my true noob knowledge, the solution was sitting in front of me the whole time (and one I had already used on the boss for a similar issue). Check the collision against what state the player is currently in.
So now he isn’t hurt when attacking the boss. At this point, the only thing I might add later is another check to make sure the player is actually facing the boss (I image going invincible during the animation with the players back to the boss).
Your second post though is extremely insightful and informative. Tons of new debug things to look into for the future. Thanks!