- Home /
OnTriggerEnter() and OnTriggerExit() called multiple times despite checks.
Yes there are many questions and answers concerning similar topics, but funny enough I have not gotten a satisfying answer out of any of those posts.
The title describes the entire problem I am experiencing, so here is the code. By the life of me I do not understand why this is called multiple times when the collider (isTrigger=true) passes through my CharacterController (maybe the problem lies in this?).
Edit: It has come up several times, so to clarify:
The EnemyAgent Script does not use the damageDealt boolean - it is only used to store it as a public variable.
There is no other collider apart from the CharacterController attached to the Gameobject in question.
Also of note might be that the triggerenter/triggerexit functions are called many, many times and not just twice.
Since there are checks in place the single most important question is: Why is the OnTriggerExit() method called prematurely - before leaving the actual collider?
using UnityEngine; using System.Collections; using System.Collections.Generic; public class HitBox : MonoBehaviour { PlayerHealth playerHealth; void Awake () { playerHealth = this.gameObject.GetComponent <PlayerHealth> (); } void OnTriggerEnter (Collider other) { if(other.gameObject.tag == "EnemyWeapon"){ EnemyAgent thisAgent = other.gameObject.GetComponentInParent<EnemyAgent>(); if (thisAgent.damageDealt) return; if (thisAgent.attacking) { thisAgent.damageDealt = true; playerHealth.TakeDamage (thisAgent.attackDamage); Debug.Log (thisAgent.ID + " in"); } } } void OnTriggerExit(Collider other){ if (other.gameObject.tag == "EnemyWeapon") { EnemyAgent thisAgent = other.gameObject.GetComponentInParent<EnemyAgent>(); if (thisAgent.damageDealt) { thisAgent.damageDealt = false; Debug.Log (thisAgent.ID + " out"); } } } }
If you are wondering why the specific enemy agent is only sought after the collider is determined - it's done this way in order to have several enemies attack the player at the same time.
Please help...
Do the things tagged "EnemyWeapon" have any child objects in their hierarchy with that tag?
Hi, thanks for your reply. No, for all intends and purposes this is the only object labeled "EnemyWeapon" in each enemy's hierarchy.
I'd log out col.gameobject.name to see who they are
Do the character controller have a rigidbody and a child collider?
Hello and thanks for replying. No, the character being hit only has a CharacterController, it does have a child collider but disabling this one did not change anything about the behaviour of the script.
I'm not sure if line 18 and 19 is required, line 20 could be
if (thisAgent.attacking && !thisAgent.damageDealt) {
I am only guessing that the return on line 19 could cause unexpected behaviour. Or maybe you need continuous collision detection on.
Hi Roman, thanks for your advice. Getting rid of the return; and using the check you proposed above did not solve the problem - this was actually how I tried it before.
Since I do not use any rigidbodies, I have no way of using continous collision detection, or does the CharacterController support this as well?
Are you sure only ONE HitBox
script and ONE collider are attached to the gameobject ?
Absolutely, as mentioned above there is another collider with isTrigger=True somewhere down the hierarchy but that one has been disabled for testing.
This is also the only instance of a model using this particular script in the entire scene, and project for that matter.
@Biggzlar Do you have a extra collider on your character controller object? If you try deactivating it. The characterController class inherits from collider and thus, has a built in support for OnTriggerEnter() stuff. When you are using another collider too, it could be that the event is registered twice. But im not sure tho. Tell me if it helped solving your problem.
Hello @Desoxi, thanks for your response. Sadly no, as mentioned above the CharacterController is the only thing providing a collider in the entire hierarchy.
@tanoshimi edited the question so I can't reply directly.
Actually the EnemyAgent script is just storing this public bool, not modifying it in any way.
Answer by LoBlanc · Dec 13, 2016 at 11:11 AM
I got this error sometimes and solved it by using a bool to control that it is entering the trigger only one time per collision
Hi! There is a boolean in place already, see "thisAgent.damageDealt". It has to be handled per attacking agent in order to have simultaneous hits from several sources call the triggers.
Answer by arsi86 · Jan 23, 2021 at 11:00 PM
I also had multiple calls of OnTriggerEnter
and OnTriggerExit
... Particulary annoyiing bug. But I've noticed that it was somehow related to dynamic light
I had in the scene. By dynamic light I mean a light source which was moving and changing intensity. It was light from camp fire object. Enabling this light was causing OnTriggerEnter
and Exit
to flicker like crazy. Anyone else had this??
Answer by GeroNL · Jan 24, 2021 at 06:57 AM
Maybe you can do in just one of OnTriggerEnter() / OnTriggerExit(), not both. And do like this :
class EnemyAgent
{
public float GotAttackedDelay = 0.5f;//seconds
[HideInInspector] public float GotAttacked = 0f;
........
void OnUpdate()
{
float timelapse = Time.deltaTime;
if(GotAttacked > 0)
GotAttacked -= timelapse;
}
}
public class HitBox : MonoBehaviour
{
....
void OnTriggerEnter(Collider other){
if (other.gameObject.tag == "EnemyWeapon" ) {
EnemyAgent thisAgent = other.gameObject.GetComponentInParent<EnemyAgent>();
if (thisAgent.GotAttacked <= 0) {
thisAgent.GotAttacked = GotAttackedDelay;
Debug.Log (thisAgent.ID + " out");
}
}
}
....
Hope it helps.