My character has two colliders on its child objects, one on a weapon and other on a shield. How do I check if the OnTriggerEnter() is triggered by the collider on the weapon and not the collider on the shield, with the target’s collider?
Thanks.
My character has two colliders on its child objects, one on a weapon and other on a shield. How do I check if the OnTriggerEnter() is triggered by the collider on the weapon and not the collider on the shield, with the target’s collider?
Thanks.
You could just give them tags and then check which tag has hit the collider.
Are you referring to other.CheckTag()? I think that is for checking tag on the gameobject colliding my character. I am interested to know which of my colliders (either the weapon collider or the shield collider) is colliding with the target’s collider.
Thanks !
You could do a component check if your shield and weapon have specific scripts pertaining to their purpose
void OnTriggerEnter(Collider col){
if(null != col.GetComponent<Sword>()){
//do sword stuff
}
}
Thanks for the reply, Laperen.
It looks like your codes are to be used in script attached to the character’s target, not on the character. If the target also have a weapon and shield, how to I check if the Sword collider on the character is colliding with the Shield collider and not colliding with the Sword collider on the target?
The character has two colliders on him, a sword and a shield. The target has similarly two colliders, on the child objects, a sword and a shield. When the OnTriggerEnter() is triggered, how do I check that it is the character’s sword and the target’s shield colliding and not other combination (like sword and sword or shield and shield)?
From my testing, it seems that the OnTriggerEnter() is called when shield and shield or sword and sword collide. Was hoping to find a way to run some codes only when it is the sword and shield colliding.
Thanks again everyone ![]()
Collision has a variable called contacts which saves an array of ContactPoints. You can access contact points and get both, thisCollider or otherCollider.
So code would look like this:
void OnCollisionEnter(Collision col)
{
foreach (ContactPoint contact in col.contacts)
{
if (contact.thisCollider.name == "Sword")
{
//Do something here
}
}
}
Thank you manifestus.
However, that only work for collision, and not trigger events. Is there a workaround or approach in getting similar information, in particularly thisCollider.name from OnTriggerEnter?
If you are trying to get the collision between a sword and a shield, then you need two colliders: one on the sword, and one on the shield. The “OnCollisionEnter” or “OnTriggerEnter” scripts need to be on either the sword or the shield. You can’t put them on the player character, because that would only get called when the player’s collider (for their body, I assume) is colliding or triggering something. So if you put it on the Sword for example, then:
void OnCollisionEnter(Collision col) {
var sword = GetComponent<Collider>(); //this is always going to be the sword, you don't need to check if it's the sword, because the script is running on the sword
var somethingElse = col.collider; //this is what the sword hit, you can check if it's the shield
}
Triggers are the same:
coid OnTriggerEnter(Collider other) {
var sword = GetComponent<Collider>(); //again, it's always the sword, since the script is on the sword, you don't need to check
if(other.name == "Shield") DoWhatever(); //you only need to check what "other" is.
}
Unless you actually need to do something with the sword’s collider, you don’t need to call GetComponent<> or anything; if the script gets triggered on the sword, then you know that the sword is one of the two things colliding. You only have to check what the other thing is.
I tried the following:
-3 colliders on the Player; one on the body, another on the sword and the last on the shield. Sword and shield are child objects of the body.
-exactly the same setup for the Enemy.
I have this code in the enemy script:
void OnTriggerEnter(Collider other)
{
if (other.tag == "CharacterBody") // I have tagged the player body collider's gameobject "CharacterBody"
{
other.GetComponent<Player>().takeDamage(swordDamage); //this line is intended to run only when the enemy's sword collider collide with the player's body collider.
}
}
When the enemy’s sword collide with the character’s body, the code works as intended. The problem is when the enemy’s shield collide with the character’s body, it also execute and deduct the sword damage.
Is there a way to check that it is the enemy’s sword triggering the OnTriggerEnter, and not other colliders, and then make the sword damage code run?
Thanks again everyone!
You could try raycasting from other collider to yours, would look something like this:
void OnTriggerEnter(Collider col){
RaycastHit hit;
Vector3 dir = transform.position - col.transform.position;
Physics.Raycast(col.transform.position, dir, out hit, 1f);
}
Make sure to test the distance of raycast, but besides that, this might do the trick ![]()
You should put a tag on the player’s sword that is different than the tag for his body. Like “CharacterSword”. And check for that instead:
void OnTriggerEnter(Collider other)
{
if (other.tag == "CharacterSword")
{
other.GetComponentInParent<Player>().takeDamage(swordDamage); //note: GetComponentInParent instead of GetComponent, assuming the player body is a parent of the player sword.
}
}
The codes work as intended when the enemy has one collider on the enemy body; Player’s sword collider collide with the enemy body collider and enemy take sword damage. However, when I attached a collider to the enemy’s shield and the shield collider collide with the player’s sword collider, the code also execute (enemy takes sword damage), which is not intended.
Ideally, there is a way to check that source collider is the enemy body collider and not the shield collider, before running the code to take sword damage.
Something like
void OnTriggerEnter(Collider other)
{
if (other.tag == "CharacterSword" && self.tag == "BodyCollider") // so that
//if it is the shield collider, the code below will not take place
{
other.GetComponentInParent<Player>().takeDamage(swordDamage); //note: GetComponentInParent instead of GetComponent, assuming the player body is a parent of the player sword.
}
}
[/QUOTE]
Thanks!
Heh, I don’t know how to make it clearer. It sounds like you’re putting a copy of the same script on the sword, the shield, and the body. Don’t! The script should just be on one of those. If you put the script only on the body, then you don’t need to check if “self” is the body. It always is, because that’s where the script is. Or, if you put the script only on the sword, you know that “self” is always the sword, because that’s where the script is.
I’d like to see your scene setup to know how the collisions are occurring.
I’ll add, if you really just want to put the script everywhere and check tags, you can check an item’s own tag by just writing “tag”:
if (other.tag == "CharacterSword" && tag == "BodyCollider")
But I can’t stress enough that it’s a bad idea to put the same script on a whole bunch of unnecessary objects if you know in advance you only want it to work for the Body. Just put it only on the Body.
That’s the problem I had… having the script (with the OnTriggerEnter method) on the player body collider gameobject, (which is the parent object of the sword and shield) but trying to determine if it is the sword collider colliding with the enemy’s body (which I could determine with other.tag). Took your advice and move the OnTriggerEnter method from the body script to a new script on the sword gameobject.
That solves the problem! The OnTriggerEnter method no longer get triggered when the shield collider hit the enemy’s body collider, only get triggered when the sword collide with the enemy’s body collider.
Thank you everyone for the patience and useful inputs! It means alot to a newbie.