Character controller trigger enter and exit loop
Hey everyone. I'm a beginner, I'm trying to figure some first person controller stuff.
There's a cube acting as a wall. What I'm trying to do is get the character to move through the wall, the wall's layer change to "PassThrough", allowing the character to pass through it, and the wall color to change, and when the player exits the wall, those same parameters to go back to their default state.
I had no problem achieving both goals by using OnTriggerEnter and OnTriggerExit.
But it seems these 2 events are getting called again and again while the player is inside the wall, meaning the wall will rapidly change from (let's say) green to white.
What am I missing? Thanks.
If the wall collider is a trigger (as it seems to be as you are using the OnTrigger() methods), isn't the player able to pass through it anyway?
Also I guess those methods are called repeatedly, because OnTriggerExit() is called by the physics after disabling the collision (by switching the layer) which will change the layer again which will cause OnTriggerEnter() to be called which will disable... ;)
Haven't tested it, But if I remember correctly, the Exit() methods are called in case of disabling the collider.
Answer by iwaldrop · Sep 07, 2016 at 04:58 AM
You'll likely want a trigger collider attached to the player which will trigger monobehaviours on other game objects. To keep things simple, just create a child game object of you player and attach a sphere collider set as a trigger. Create and attach a script to this game object which will does the following:
(psudocode that probably won't work as is)
void OnTriggerEnter(Collider other) {
TryTrigger(other.gameObject, enter: true, sender: this) // or sender as player?
}
void OnTriggerExit(Collider other) {
TryTrigger(other.gameObject, enter: false, sender: this) // or sender as player?
}
void TryTrigger(GameObject otherGameObject, bool enter, Object sender) {
var triggerable = otherGameObject.GetComponent<Triggerable>()
if (triggerable != null) {
triggerable.Trigger(enter, sender)
}
}
Then create an abstract Triggerable
class which inherits from MonoBehaviour
which defines the contract which all triggerables will implement. In this simple example, you'll need two classes:
public void abstract class Triggerable: MonoBehaviour {
public void Trigger(Bool enter, Object sender);
}
public class PassThroughWall: Triggerable {
public void Trigger(Bool enter, Object sender) {
// do the things that you're currently doing in your existing script
}
}
Now just attach the PassThroughWall script to your wall section which you want to pass though and try to walk though it. I haven't tested this code so you'll likely have to tweak it slightly, but the idea is a solid, simple, way to approach the problem.
You can now make all sorts of things triggerable by the player approaching. I'd recommend enhancing this technique and put the trigger and triggerable game objects on special layers which will reduce the overhead which would be caused by the collider calling get component on every game object that it collides with.
Good luck!
Thank you for the well written and thorough reply, it works flawlessly!
Your answer
Follow this Question
Related Questions
Text disappear on OnTriggerExit() 1 Answer
How do I destroy an instantiated game object when player leaves trigger area? 1 Answer
How can I make a collider that gives me stat up to stop giving me it? 0 Answers
math.Lerp not correct? 1 Answer
Im trying to turn off a sound when i leave a trigger collider 0 Answers