I’m now having a problem in my game since the upgrade to 3.2: in my elevator algorithm I parent my player to the elevator gameobject in the OnTriggerEnter function. But when this has happened, I don’t receive an OnTriggerStay, nor an OnTriggerExit call anymore.
Is this normal behaviour since the update, and if so, what is the best way to solve my problem? Since I unparent my player in the OnTriggerExit call, but now I don’t get that call anymore at all!
If there is no quick solution, can someone please give me a windows download link for the previous version, because I don’t have much spare time…
I have switched back to 3.1 and had the TriggerExit messages again, without changing my code… It could be that the trigger messages were erroneous in version 3.1 then, but there is definitely a difference between the 2 versions.
I think I found something, In my project the problem isnt about be parent or not, In my project my main character has 3 scripts added to him, are:
1 - the character mover
2 - the character Damage
3 - the character Animator
4 - another one to aditional commands such as getting in vehicles, turn on or of the first script, get in platforms, etc.
If I turn of the 4th script, everything. This simple thing gives me multiple problems
Not exactly, I have a character that have multiple scripts to control him, even unparented the OnTriggerExit doesnt work with him since 3.2 (was working ok on 3.1) , I changed his scripts and now it works, but if parented the problem still happens.
The dirty solution I found is to deny the triggering every 0.1s so it would re-check the triggering so if I leave the trigger in 0,1 seconds it will be the artificial “ontriggerexit” , worked perfect on 3.2 but on 3.3… I dont know why but triggering seems to be slowly and the effects arent the best, the retrigger is too slow and the character moves, so I dont have a natural or artificial solution, my solution now is to make another trigger around to untrigger the first trigger (I am not comfortable to make it but my project cannot stop).
My problem is the same, however, I’m a step further: It seems as im OnTriggerEnter gets called all the time.
I made a “rope” for 2D platforming games and the idea is that every segment of the rope is a trigger. When the player enters, he gets parented and a number is dadded to a counter. When the player exits anumber is substraced. When the number equals 0 the player gets unparented (he slipped off the rope). Take a look: http://forum.unity3d.com/threads/76721-working-2D-rope-concept-for-sidscrolling-games-(for-free)
For convenience I’ll post the relevant part of code here:
/*
--- script used to parent player or other objects to a rope during gameplay ---
Use this script in combination with a rope. Currently only works with triggers.
The player has to press Up, in order to stick
*/
function OnTriggerEnter (collision: Collider){
var playerObject = collision.gameObject.transform.parent.gameObject;
if(Input.GetAxisRaw("Vertical") != 1 playerObject.GetComponent(ClimbingController).enabled == false)
return;
playerObject.GetComponent(ClimbingController).AddSegment(1);
//set up the controller script (leave speed values unchanged)
playerObject.GetComponent(ClimbingController).SetUpController(0.0, 0.0, 0.0, true, false, false, true);
// Debug.Log (Time.time + collision.gameObject.name + gameObject.name + playerObject.name);
playerObject.transform.parent = transform;
playerObject.GetComponent(ClimbingController).SetXOffest(0.0);
playerObject.GetComponent(MyController).enabled = false;
playerObject.GetComponent(ClimbingController).enabled = true;
}
function OnTriggerExit (collision: Collider){
var playerObject = collision.gameObject.transform.parent.gameObject;
if (playerObject.GetComponent(ClimbingController).enabled == false)
return;
playerObject.GetComponent(ClimbingController).AddSegment(-1);
// Debug.Log (Time.time + playerObject.name + gameObject.name + "exited collision");
//the player will be touching several sements at a time. We want to dismount the player
//only if he exited the last trigger he was in
if(playerObject.GetComponent(ClimbingController).GetSegments() == 0){
//the following two make the player fall down straight
playerObject.GetComponent(MyController).jump.isPrimitive = true;
playerObject.GetComponent(MyController).movement.momentum = 0;
//now unparent
playerObject.transform.parent = null;
//and acivate the right controller
playerObject.GetComponent(MyController).enabled = true;
playerObject.GetComponent(ClimbingController).enabled = false;
}
}
function JumpOff(theDirection: int, jumper: GameObject){
// blah blah, this stuff works fine
}
Uncommenting the debugging lines reveals that OnTriggerEnter gets called all the time, as long as I am touching the segment. OnTriggerExit does not get called at all. But it does get called when I am not parented to the rope (the player gets only parented if he is holding up)
This worked perfectly fine on 3.1
It looks as if I have found a proper workaround. It’s late and I doubt i will have time to go into detail tomorrow, especially since I have to to a bit of testing.
Essentially I used to approach by this other guy where OnTriggerEnter gets cancelled immediately if a certain flag is set. But instead of using a boolean I store the trigger’s object in a hashtable and OnTriggerEnter gets cancelled if the trigger is already in this hashtable. This approach allows me to track several triggers at once, since my player is rarely touching just one segment of the rope.
So here is what I figure: You must prevent OnTriggerEnter() from being called after the first time. The best way seems to have some sort of check at the very beginning and if it fails (or succeeds, that’s up to you) immediately end the function. A boolean should do fine as the user Barf did it. I used a hashtable since I need to be able to check for several objects without knowing which one.
var someFlag: boolean
funtion OnTriggerEnter(other: Collider){
if(!someFlag)
return;
// here goes the rest
}
my approach:
var someHashtable: Hashtable;
//blah bla, fill the table with stuff
funtion OnTriggerEnter(other: Collider){
if(someHashtable.ContainsValue(other.gameObject))
return;
//do stuff
}
Whatever you do, do not base your check on parenting. I tried that approach before and it did not work. Only after doing a boolean check did it work.
Also this odd behaviour only seems occur if OnTriggerEnter does something related to parenting.
Just found this thread. I have the same problem with triggers when parenting and the solutions you guys suggested haven’t worked for me. Is this a bug of this Unity version? I’m using Unity 3.3 and tested it with Windows 7 and with Snow Leopard.