- Home /
How do I make OnTriggerEnter() respond to just one collider?
Hi guys,
I have some checkpoints in my game, and I've decided to use OnTriggerEnter() for them. Here is the implementation in Checkpoint.js:
function OnTriggerEnter (other : Collider) {
if (other == engine.collider);
levelManager.SendMessage("RegisterCheckpointHit");
}
levelManager is set to a shared instance of the prefab LevelStateManager, and it has a script attached called LevelStatus.js. The implementation of RegisterCheckpointHit is as follows:
function RegisterCheckpointHit()
{
if (checkpointsHit < numCheckpoints) checkpointsHit++;
Debug.Log("Checkpoint Hit");
}
The RegisterCheckpointHit() function works exactly as expected, however OnTriggerEnter gets called multiple times because the player object has multiple colliders. The player object consists of a character with multiple colliders, as well as an engine with just one collider. Because there are multiple colliders, the collider for the checkpoint gets triggered multiple times. The attempt to restrict it to the engine's collider with the following code:
if (other == engine.collider);
Doesn't seem to be working. What am I doing wrong?
MachCUBED
Answer by Kryptos · Apr 06, 2012 at 08:16 AM
Take a look at Layer-Based Collision Detection.
What you can do is having a child object on your player with a collider that is in the only layer that collides with the layer of your triggers.
Putting my checkpoints on their own layer, then setting the Checkpoints layer to only interact with the Jetpack layer didn't do the job either, OnTriggerEnter is still being triggered twice by the sole collider of the Jetpack. This is with the code in LevelStatus.js set to the following:
function RegisterCheckpointHit() { if (checkpointsHit < numCheckpoints) { checkpointsHit++; }
if (checkpointsHit > numCheckpoints) { checkpointsHit = numCheckpoints; }
if (checkpointsHit == numCheckpoints) { NotificationCenter.DefaultCenter().PostNotification(this, "ActivateFinishLoop"); }
Debug.Log("Checkpoint Hit"); }
wow, so stupid that ontriggerenter gets called for the parent object and all children with colliders of the parent object. been confused for months as to why my guy was losing 2 lives after being killed!
Answer by simonmc · Apr 06, 2012 at 12:35 AM
remove the semicolon in your if (other == engine.collider)
line
to avoid all sorts of errors with if's in future, make use of curly braces for if statements.
if (other == engine.collider) {
levelManager.SendMessage("RegisterCheckpointHit");
}
When I tried the above code, I got a thing where the checkpoint gets activated twice for some strange reason.
I also added a boolean to deter$$anonymous$$e if the checkpoint has been hit or not.
private var passed = false;
And the new contents of OnTriggerEnter():
if (other == engine.collider)
{
if (!passed)
{
Debug.Log("Registering Checkpoint Notification");
NotificationCenter.DefaultCenter().PostNotification(this, "RegisterCheckpointHit");
passed = true;
}
}
Your code helped, but I still have a strange issue nonetheless. Although the notification is only being posted once, the rest of the dependent code is being run twice, even though RegisterCheckpointHit() is implemented in two separate files with different implementations.
LevelStatus.js:
function RegisterCheckpointHit()
{
if (checkpointsHit < numCheckpoints) checkpointsHit++;
Debug.Log("Checkpoint Hit");
}
HUD.js
function RegisterCheckpointHit ()
{
timeLeft += checkpointBonus;
Debug.Log("TI$$anonymous$$E EXTENDED");
}
Strange, huh?