- Home /
Alternate for OnTriggerExit???
As many of us already discussed OnTriggerExit is being a son of a bitch by not working properly. I guess its a bug or whatever.Anyways, i have an object("GameObject") that spawns lots of static cubes. The cubes have a Tag("Block"). I put a script on "GameObject".....
var coll : boolean = false;
function OnTriggerEnter(other : Collider)
{
if(other.gameObject.CompareTag("Block"))
{
coll = true;
}
}
function OnTriggerExit(other : Collider)
{
if(other.gameObject.CompareTag("Block"))
{
coll = false;
}
}
OnTriggerEnter works fine. But OnTriggerExit dosent. Is there another way i can do this? Sincerly, Kibbles (-.-)
Answer by aldonaletto · Oct 14, 2011 at 09:08 PM
I suspect that your problem has a different cause: since there are several Block objects around, the trigger Enter and Exit events may get fooled: coll becomes true when any Block enters the trigger, and turns to false when any Block exits - no matter how many Block objects are inside the trigger.
Anyway, you could try something like @DaveA suggested:
var coll = false; var stay = false;
function OnTriggerStay(other: Collider){ if (other.CompareTag("Block")){ stay = true; // set stay if any Block inside the trigger } }
function FixedUpdate(){ if (stay){ // if any Block inside the trigger... coll = true; // set coll stay = false; // and prepare flag for next cycle } else { // if stay not set, no Blocks are inside coll = false; // thus clear coll } } This code sets coll when the Block enters the trigger, and clears it when the Block exits. You must use FixedUpdate to control coll because Trigger events occur in the physics cycle. Use Update to do the rest - including to read coll.
I suppose that coll will become false only when no more Blocks are inside the trigger (I didn't test this).
EDITED: Triggers are good for detecting when things enter and exit, but if something is created or teleported inside the trigger, nothing happens.
There are several ways to detect if there are objects in a given volume, but I think the easiest is to use Physics.OverlapSphere: you inform radius and position of an imaginary sphere, and the function returns all colliders that touch or are inside it. Since other objects - like the ground or scene details - may be also detected, you must tag each cube you create with a specific word - "Cube", for instance - so you can check if any "Cube" is returned by OverlapSphere and ignore the rest.
Place the code below in your cube creator script, and call the function SpawnCube when you want to create a new cube. The routine checks if some object tagged "Cube" intersects the sphere, and aborts if any one found, otherwise it instantiates the object referenced by prefab in the current position.
var prefab: GameObject; // drag your cube prefab here var radius: float = 2; // cube-free sphere radius
function SpawnCube(){ var cols = Physics.OverlapSphere(transform.position, radius); for (var col: Collider in cols){ if (col.tag == "Cube"){ // if any cube intersects sphere... return; // abort instantiation } } // no Cube found, instantiate new cube: var cube = Instantiate(prefab, transform.position, transform.rotation); cube.tag = "Cube"; // and tag the new cube as "Cube" }
i dont know anymore. It looks like all that did was add another variable that checks when coll checks. And when i exit the cube, now there are 2 variables that dont change ins$$anonymous$$d of one. I didnt think it would be this difficult. I am actually an 3d animator, not a programmer. First game engine i ever used was blender game engine hahaha. Ahhh logic bricks, those where the days...Anywways, im on the brink of giving up but what if, ins$$anonymous$$d of triggers, i say IF creator is Near any tag of Block. How would i write that? Does it involve Vector3.Distance or something?
To all the great people on this site that take the time to help us clueless artists figure this stuff out, just wanna say thanks! This stuff isnt easy i dont care who you are. It definetly takes some studying and trial and error.
In a second read, I noticed that the cubes are static - so, who's moving? The block creator? What exactly are you trying to do? Create cubes with a $$anonymous$$imum space between them?
The block creator is moving. Everytime i press a key, it spawns a block. I dont want the blocks i create to collide with each other. Is there a way i can do this without that darn trigger system?
I edited my answer to include an example of how to check if some cube is inside a given spherical volume, and instantiate the new cube if no other is touching or inside the volume.
Answer by DaveA · Oct 14, 2011 at 07:20 PM
You could monitor OnTriggerStay from Update. See when it is/was/is-no-longer 'staying'
Hmm thats what i started doing but i dont know how to check to see when it is no longer.
Answer by Bunny83 · Oct 17, 2011 at 11:15 PM
I guess you just forgot to add a rigidbody to your cubes? It can be kinematic but you need one on the object that is moving or the collision system won't work. What Unity version do you use? One of the recent releases have a fix for OnTriggerExit when you destroy an object.
Answer by mercury_storm · Nov 30, 2011 at 11:59 AM
An alternate method would be to have OnTriggerStay set a timer to 0.1 seconds (or so), while having an Update function constantly subtracting Time.deltaTime from that timer. If OnTriggerStay can no longer set that timer to 0.1 seconds, then Update() will win, and get that timer to 0.0
Once the timer is at 0.0 or less, then Update() can call OnTriggerExit() manually.
$$anonymous$$ake sure you check the timer before decreasing it by deltaTime- if your framerate is lower than 10 it could trigger by accident otherwise!
I've been trying a bunch of different things and this is what I am using at the moment as well. Feels like a nasty work around though. It seems though that the OnTriggerExit is worthless if you want to destroy an object that is in a trigger. The Exit never gets triggered.
Answer by bobthefish · Apr 16, 2012 at 09:54 AM
I had issues with OnTriggerEnter/Exit being inconsistent, and I was trying to use the triggers as zones for my players. I couldn't use the approach Aldo Naletto suggested because that would limit me to spherical zones, and my trigger objects can be all kinds of shapes (mostly rectangular).
In the end the solution I came up with was to put all the triggers in a layer called "Zone" and then in Update for the player object do a 1 unit OverlapSphere with the Zone layer. You could optimise this by then adding a delay before it checks again.
If you wanted you could probably even get this to call "OnZoneEnter", "OnZoneStay" (if you do the check every frame) and "OnZoneExit" in the trigger object whenever its zone changes, and now you've got exactly the behaviour triggers were supposed to have in the first place :)
In case anyone's curious, in places where the player was touching two zones I used GetClosestPointOnBounds to determine which zone edge is closest to the centre of the player.
Just like to add that OverlapSphere just checks againse tha AABB (axis aligned bounding box) of the colliders and not the true shape so your zones are always boxes.
They might change that in the future but for the time being it just checks the AABB.
Your answer
Follow this Question
Related Questions
OnTriggerEnter only working once. 0 Answers
Problem with OnTriggerExit 1 Answer
Varaible not decementing OnTriggerExit 1 Answer
OnTriggerEnter Question 0 Answers
OnTriggerExit happens too soon! 1 Answer