0
\$\begingroup\$

I have created a trigger zone to make sure that only one gameobject should pass through the trigger zone at once. Other gameobjects approaching the trigger zone are made to stop just outside the trigger zone if there is already a gameobject in the trigger zone. I could get things working up until here. Now, I need to make sure that the gameobject that got to the trigger zone first and started to wait first is allowed to pass first while others wait and then the second gameobject is allowed to pass and so on. I am stuck at this part.

\$\endgroup\$
1
\$\begingroup\$

Myself I'd be tempted to do it like this - toggling on & off the isTrigger state to make the collider a hard boundary when I want it to be, and passable other times.

IgnoreCollision lets the first object inside bypass the repulsion applied to other objects that try to intersect the collision zone. (Depending on your setup, you may need to ignore a few other items)

[RequireComponent(typeof(Collider))]
public class PassOneTrigger : MonoBehaviour {
    Collider _collider;

    void OnTriggerEnter(Collider other) {

        // Initialize a reference to our attached collider.
        if(_collider == null)
            _collider = GetComponent<Collider>();

        // If we manage to get two OnTriggerEnter messages in one frame,
        // ignore the second.
        if(_collider.isTrigger == false)
            return;

        // The object that just entered our trigger volume is allowed to stay.
        Physics.IgnoreCollision(collider, other, true);

        // Everything else should be repelled. Make the collider solid.
        collider.isTrigger = false;  

        // Wait until the first object leaves, then switch back to trigger behaviour.
        StartCoroutine(WaitUntilClear(other));
    }

    IEnumerator WaitUntilClear(Collider other) {
        while(other != null) {
            // Wait a frame.
            yield return null;

            // Check whether both colliders contain the same point
            // ie. whether they still overlap.
            Vector3 point = _collider.ClosestPoint(other.bounds.center);
            if(point != other.ClosestPoint(point))
                break;
        }

        // Clear the ignore collision mark
        if(other != null)
            Physics.IgnoreCollision(_collider, other, false);

        // Return to trigger behaviour to let the next object in.
        _collider.isTrigger = true;
    }
}

Put this on an object with just one collider - the trigger you want to use as the outer boundary. If you need other triggers, attach them to separate objects to make sure their messages get to the right places and there are no crossed wires.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.