Conditional Triggers

Hello everyone,
I’m trying to figure out how to create conditional triggers.

Example: Where a second trigger wont activate until the first trigger has been activated. I’m thinking like a parent trigger, perhaps?

I have a basic trigger set up, but is it possible to add conditions without making everything the same? or without having the same output every time.

Hope I made sense, any info would be greatly appreciated. Thank you in advance.

Depends on what you are doing. Say you have a person with a collider and they walk into a trigger collider near a box. The box opens and you get something out of it. Player leaves and comes back and opens the box again, this time getting a different item.

In this case, you just have to track a variable to know what stage you’re on for the triggers. It would work the same if you’re trying to do something like stepping on several panels to open a door. If each panel has a trigger collider on it and you have to step on them in a certain order, you have to keep track of it in variables and just update that variable as you step on each platform and then do an if check.

You could also just turn off and on colliders after steps are completed.

UnityEvents are a handy way to make a little script go a long way. For example, you could create a C# script named TriggerEvents:

using UnityEngine;
using UnityEngine.Events;

public class TriggerEvents : MonoBehaviour {

    [Tooltip("Object that enters this trigger must have this tag.")]
    public string requiredTag = "Player";

    public UnityEvent onTriggerEnter = new UnityEvent();
    public UnityEvent onTriggerExit = new UnityEvent();

    void OnTriggerEnter(Collider other) {
        if (other.CompareTag(requiredTag)) onTriggerEnter.Invoke();
    }

    void OnTriggerExit(Collider other) {
        if (other.CompareTag(requiredTag)) onTriggerExit.Invoke();
    }
}

Then:

  • Disable the second trigger’s collider.

  • Add the TriggerEvents script to your first trigger and inspect it.

  • In the On Trigger Enter event section, click “+” to add a new event handler. Assign the second trigger’s collider’s enabled property, and tick the checkbox to specify that it should enable the collider.

If you need to keep track of more than which triggers have been entered, you’ll need to set up a variable system as Brathnann suggests. You could add an empty GameObject with a script named Flags like this:

using UnityEngine;

public class Flags : MonoBehavior {

    [System.Serializable]
    public class Flag {
        public string name;
        public bool value;
    }

    public Flag[] flags;

    public void Set(string flagName) {
        Lookup(flagName).value = true;
    }

    public void Clear(string flagName) {
        Lookup(flagName).value = false;
    }

    public Flag Lookup(string flagName) {
        foreach (var flag in flags) {
            if (string.Equals(flag.name, flagName)) return flag;
        }
        return null;
    }
}

This will let you define a set of flags (true/false values) that you can set or clear.

Then change your TriggerEvents script to this:

using UnityEngine;
using UnityEngine.Events;

public class TriggerEvents : MonoBehaviour {

    [Tooltip("Object that enters this trigger must have this tag.")]
    public string requiredTag = "Player";

    public string requiredFlag;
    public bool requiredValue;

    public UnityEvent onTriggerEnter = new UnityEvent();
    public UnityEvent onTriggerExit = new UnityEvent();

    private Flags flags;

    void Awake() {
        flags = FindObjectOfType<Flags>();
    }

    void OnTriggerEnter(Collider other) {
        if (other.CompareTag(requiredTag)) {
            if (flags.Lookup(requiredFlag).value == requiredValue) {
                onTriggerEnter.Invoke();
            }
        }
    }

    void OnTriggerExit(Collider other) {
        if (other.CompareTag(requiredTag)) onTriggerExit.Invoke();
    }
}

This will let you specify a required flag and value (true or false) for the trigger to fire.

You can also use the On Trigger Enter and On Trigger Exit event blocks to set other flags by assigning the Flags component and selecting the Set or Clear methods.

You can get a lot of use out of these two short scripts.

(Note that, for clarity, I didn’t include any error handling such as verifying that the flag names are actually defined in the Flags component.)

Thank you all for the feedback. It’ helped me out a lot trying to get that figured out but with your help, I was able to get it done. I apologize for the late reply by the way.
cheers!

So for my artist and I, he can’t code worth nothing. We usually use states to control things… simple states like disabling/enabling objects.

In this situation we literally would have 2 triggers, the first trigger is active, the other disabled. When the 1st is entered we’d then disable the 1st, and enable the second. The second just isn’t available until the first is touched.

You can do this with UnityEvent by literally targeting the second trigger, and calling the ‘GameObject.SetActive’ method on it through the inspector.

So long before UnityEvent came out I created a UnityEvent thing we call 'Trigger’s. We actually streamline the enable/disable bit through this.

With it I create little lego pieces for him. Things like "t_EnterTrigger’ which listens for entering a trigger, and blasts of the UnityEvent like ‘Trigger’ of ours (the t_ bit is so he can click add component, type t_, and get a list of just the triggers he can use).

A simplified version for UnityEvent would be like:

public class t_TriggerEnterByTag : MonoBehaviour
{

    public UnityEvent Trigger;
    public string Tag;

    private void OnTriggerEnter(Collider other)
    {
        if(string.IsNullOrEmpty(Tag) || other.CompareTag(Tag))
        {
            Trigger.Invoke();
        }
    }

}

Now you have a reusable little script that you can monitor for the player entering by tag… or other things entering by their tag. And just toggle states of objects to control flow.