0
\$\begingroup\$

I'm making a 2D platformer with Unity. I want to create a pressure pad in order to open a door and I want the door to open when the player is on the pressure pad and close in few seconds after the player leaves the pressure pad. I've tried different ways but none of them worked. In this case, the door should be open upwards and close downwards. Also, I already created some animations (idle, open and close) for the door but don't know how to make a connection between these two objects then play the animations at the proper time. Thank you in advance.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class PressurePad: MonoBehaviour
{
    public UnityEvent OnActivate;
    public UnityEvent OnDeactivate;

    int objectsInContact;

    IEnumerator Timer()
    {  
        yield return new WaitForSeconds(6);
        OnDeactivate.Invoke();
    }
    void OnTriggerEnter2D(Collider2D other)
    {
        objectsInContact++;
        if (objectsInContact == 1 && OnActivate != null) OnActivate.Invoke();
    }

    void OnTriggerExit2D(Collider2D other)
    {
        objectsInContact--;
        if (objectsInContact == 0 && OnDeactivate != null) OnDeactivate.Invoke();
        StartCoroutine(Timer());
      
    }

}

enter image description here

\$\endgroup\$
2
0
\$\begingroup\$

You're very close, but you're firing your deactivate event twice: once the instant the pad is empty, and then again after a delay.

Delete the first one, and also make sure you stop the timer if the player returns to the pad before the time is up:

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 
using UnityEngine.Events; 

public class PressurePad: MonoBehaviour {
 
    public UnityEvent OnActivate; 
    public UnityEvent OnDeactivate; 

    public float deactivationDelay = 6f;

    int objectsInContact;
    Coroutine waitingToDeactivate;


    IEnumerator Timer() { 
        yield return new WaitForSeconds(deactivationDelay);

        // Tell our listeners we're switched OFF.
        if (OnDeactivate != null) 
            OnDeactivate.Invoke(); 

        // Return to ready-to-activate state:
        waitingToDeactivate = null;
    } 

    void OnTriggerEnter2D(Collider2D other) { 
        objectsInContact++; 
        
        // Pressure pad pressed.
        if (objectsInContact == 1) {

            if (waitingToDeactivate != null) {
                // Cancel deactivation timer. 
                StopCoroutine(waitingToDeactivate);
                waitingToDeactivate = null;

            } else if (OnActivate != null) {
                // Tell our listeners we're switched ON.
                OnActivate.Invoke(); 
            } 
        }
    }

    void OnTriggerExit2D(Collider2D other) { 
        objectsInContact--; 

        // Pressure pad released.
        if (objectsInContact == 0) {
            // Start a delay before telling anyone.
            waitingToDeactivate = StartCoroutine(Timer()); 
        } 
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Thank you. This works better than the previous one. The only thing I need to fix is playing the animation (named OpenWhenOn) as long as the player is on the pressure pad. Should I use something like anim.Play ("OpenWhenOn"); in objectsInContact if statement? \$\endgroup\$
    – Ali
    Dec 22 '20 at 16:39
  • \$\begingroup\$ This sounds like a problem in your door state machine, not a problem that the pressure switch should know anything about. Want to post a new question, showing the animator control graph state machine you've set up for your door? \$\endgroup\$
    – DMGregory
    Dec 22 '20 at 16:40
  • \$\begingroup\$ Sure, I'll ask a new question. Thanks for everything. \$\endgroup\$
    – Ali
    Dec 22 '20 at 16:43

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.