Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[SOLVED] Playing door open animation on button press and other condition?

Discussion in 'Scripting' started by topherbwell, Jun 17, 2015.

  1. topherbwell

    topherbwell

    Joined:
    Jun 8, 2015
    Posts:
    180
    I am writing a door open script that detects if the player is near the door, displays a UI text if so, and then allows the player to press a button to open the door, which should then stay open for a few seconds and play the closing animation.

    I have most of this working, but now I am stuck trying to figure out how to play the animations. I have already made two animation clips; one for open and one for close. Can someone help me figure out how to play the open animation, wait a few seconds, and then play the close animation?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class doorScript : MonoBehaviour
    6. {
    7. //box collider to see if player is near the door
    8.      public Collider theCollider;
    9. //canvas with text that reads "Press R to open"
    10.      public Canvas doortext;
    11.      public bool doorisClosed;
    12.  
    13.      void Awake ()
    14.      {
    15.           theCollider = GetComponent <BoxCollider> ();
    16.           doortext = doortext.GetComponent<Canvas> ();
    17.           doortext.enabled = false;
    18.      }
    19.  
    20.      void Update ()
    21. //if the door text is enabled and the player presses R, go to changeDoorState
    22.      {
    23.           if (doortext.enabled == true && (Input.GetKeyDown(KeyCode.R)))
    24.           {
    25.                changeDoorState();
    26.           }
    27.      }
    28.  
    29.      void changeDoorState ()
    30. //this is the part I need help with.
    31.      {
    32.           if (doorisClosed == true)
    33.           {
    34.                //play the open animation
    35.                doorisClosed = false;
    36.                //wait for () seconds
    37.                //play the close animation
    38.                doorisClosed = true;
    39.           }
    40.      }
    41. //checks to see if the player is in the collider, and displays the door text if so
    42.      void OnTriggerEnter(Collider other)
    43.      {
    44.           if(other.gameObject.tag == "Player")
    45.           {
    46.                doortext.enabled = true;
    47.                Debug.Log("player detected");
    48.           }
    49.      }
    50. //checks to see if player has left the collider, and disables door text if so
    51.      void OnTriggerExit(Collider other)
    52.      {
    53.           if (other.gameObject.tag == "Player")
    54.           {
    55.                doortext.enabled = false;
    56.                Debug.Log("player left");
    57.           }
    58.      }
    59. }
    60.  
     
  2. parandham03

    parandham03

    Joined:
    May 2, 2012
    Posts:
    174
    topherbwell likes this.
  3. topherbwell

    topherbwell

    Joined:
    Jun 8, 2015
    Posts:
    180
    I will most likely need to use the coroutine as this same mechanic is going to translate into some other features for which i'll need to be able to use WaitForSeconds.

    The part I'm having the trouble with the most is just playing the animation. On line 34, i'm just not sure how to type that I want to play a certain animation clip.
     
  4. parandham03

    parandham03

    Joined:
    May 2, 2012
    Posts:
    174
    Update your code with bellow code
    Code (CSharp):
    1. void Update ()
    2. //if the door text is enabled and the player presses R, go to changeDoorState
    3. {
    4.       if (doortext.enabled == true && (Input.GetKeyDown(KeyCode.R)))
    5.       {
    6.            StartCoroutine("changeDoorState");
    7.       }
    8. }
    9. IEnumerator changeDoorState ()
    10. {
    11.     //play the open animation
    12.     //>>>>>>>>>>>>>>>>>>>Add Open animation line here<<<<<<<<<<<<<<<<<<<
    13.    
    14.     //wait for () seconds
    15.     yield return new WaitForSeconds(10);
    16.  
    17.     //play the close animation
    18.     //>>>>>>>>>>>>>>>>>>>Add Close animation line here<<<<<<<<<<<<<<<<<<<
    19.        
    20. }
     
    CSmithh and topherbwell like this.
  5. topherbwell

    topherbwell

    Joined:
    Jun 8, 2015
    Posts:
    180
    Thank you again; I think this has me 90% of the way there, but I'm still having trouble playing the animations. Most of this script is based off of a tutorial I found which uses JavaScript, which I know nothing about. I converted the bulk of that script into C# the best I can with my limited understanding, but it seems that I've had to add quite a few things to get the same functionality so far. I'm guessing that JavaScript doesn't necessarily need to use a coroutine for some reason?

    On line 32 and 37, I am being told I need an object reference, which is no suprise, but I'm not sure how I should be implementing that. I don't have the animation clips currently attached to anything; could someone help point me in the right direction on how to implement them? I tried putting them in an animator on the door itself, but the animator wants to use either the open or close animation as the default state, when really I want the default state to just be static.

    How do I get the animations to actually play by script and if I do need to associate the animations with an object, what would be the best way to go about that?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class doorScript : MonoBehaviour
    6. {
    7. //box collider to see if player is near the door
    8.      public Collider theCollider;
    9. //canvas with text that reads "Press R to open"
    10.      public Canvas doortext;
    11.      public bool doorisClosed;
    12.  
    13.      void Awake ()
    14.      {
    15.           theCollider = GetComponent <BoxCollider> ();
    16.           doortext = doortext.GetComponent<Canvas> ();
    17.           doortext.enabled = false;
    18.      }
    19.  
    20.      void Update ()
    21.      { //if the door text is enabled and the player presses R, start coroutine
    22.           if (doortext.enabled == true && (Input.GetKeyDown(KeyCode.R)))
    23.           {
    24.                StartCoroutine ("changeDoorState");
    25.           }
    26.      }
    27.  
    28.      IEnumerator changeDoorState ()
    29.      {
    30.           if (doorisClosed == true)
    31.           {
    32.                Animation.Play("doorOpen");
    33.                door isClosed = false;
    34.              
    35.                yield return new WaitForSeconds (5);
    36.  
    37.                Animation.Play("doorClose");
    38.                door isClosed = true;
    39.           }
    40.      }
    41. //checks to see if the player is in the collider, and displays the door text if so
    42.      void OnTriggerEnter(Collider other)
    43.      {
    44.           if(other.gameObject.tag == "Player")
    45.           {
    46.                doortext.enabled = true;
    47.                Debug.Log("player detected");
    48.           }
    49.      }
    50. //checks  to see if player has left the collider, and disables door text if so
    51.      void OnTriggerExit(Collider other)
    52.      {
    53.           if (other.gameObject.tag == "Player")
    54.           {
    55.                doortext.enabled = false;
    56.                Debug.Log("player left");
    57.           }
    58.      }
    59. }
    60.  
     
  6. topherbwell

    topherbwell

    Joined:
    Jun 8, 2015
    Posts:
    180
    Ok I figured this out. Or at least figured out a way to make it work. What I did was create a third animation for the door where I just didn't animate the door at all and called it doorIdle. I put this on an animator controller and attached that to the animator on the door. I then dragged my doorOpen and doorClose animation onto the animator controller and did not set up any transitions or anything.

    Once that was set up on the door, I just added a public Animator anim; and then in the start anim = getComponent<Animator>();

    This is all I needed in order to get the script to play the animations. I needed the animations in an animator even though I was not using any transitions and needed another "animation" in order to have a static idle state. This works, but if anyone knows a more efficient way to eliminate the "idle" placeholder I'd be interested to hear.

    The tutorial I based all of this on was written in JavaScript and was using some outdated features such as the old GUI system and animation systems. Here is a link to the video for reference; I hope this helps in case anyone else is looking for a working way to do this using C#.

    Here is the code that is working now, in case anyone is interested:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class doorScript : MonoBehaviour
    6. {
    7. //box collider to see if player is near the door
    8.      public Collider theCollider;
    9.      public Canvas doortext;
    10.      public bool doorisClosed;
    11. //I added the following line for referencing the animator
    12.      public Animator anim;
    13.  
    14.  
    15.      void Awake ()
    16.      {
    17.           theCollider = GetComponent <BoxCollider> ();
    18.           doortext = doortext.GetComponent<Canvas> ();
    19.           doortext.enabled = false;
    20. //to get the animator component
    21.           anim = GetComponent<Animator> ();
    22.      }
    23.  
    24.      void Update ()
    25.      {
    26.           if (doortext.enabled == true && (Input.GetKeyDown(KeyCode.R)))
    27.           {
    28.                StartCoroutine ("changeDoorState");
    29.           }
    30.      }
    31.  
    32.      IEnumerator changeDoorState ()
    33.      {
    34.           if (doorisClosed == true)
    35.           {
    36.                anim.Play("doorOpen");
    37.                doorisClosed = false;
    38.                yield return new WaitForSeconds (5);
    39.                anim.Play ("doorClose");
    40.                doorisClosed = true;
    41.           }
    42.      }
    43.  
    44.      void OnTriggerEnter(Collider other)
    45.      {
    46.           if(other.gameObject.tag == "Player")
    47.           {
    48.                doortext.enabled = true;
    49.           }
    50.      }
    51.  
    52.      void OnTriggerExit(Collider other)
    53.      {
    54.           if (other.gameObject.tag == "Player")
    55.           {
    56.                doortext.enabled = false;
    57.           }
    58.      }
    59. }
    60.  
     
    JimmyKadesch likes this.
  7. topherbwell

    topherbwell

    Joined:
    Jun 8, 2015
    Posts:
    180
    Improved. I also added the following snippet. this makes the door text disappear while the door is in the open position, so that you are told to "Press R to open" only when you are actually able to do so.
    Code (csharp):
    1.  
    2.      void OnTriggerStay(Collider other)
    3.      {
    4.      if (other.gameObject.tag == "Player" && doorisClosed == false)
    5.           {
    6.           doortext.enabled = false;
    7.           }
    8.      if (other.gameObject.tag == "Player" && doorisClosed == true)
    9.      {
    10.           doortext.enabled = true;
    11.      }
    12. }
    13.  
     
    Last edited: Jun 18, 2015
  8. DannyCampi

    DannyCampi

    Joined:
    Apr 19, 2017
    Posts:
    1
    Hello I want to only open/close the door when the "Player" is near te door or the door hangle which is an empty gameobject. Also that the message appears only when Im near the door. This is my code
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class doorOpenandClose : MonoBehaviour {
    5.  
    6.     //Text variables
    7.     public bool T_ActivatedOpen = true;
    8.     public bool T_ActivatedClose = false;
    9.     public bool activateTrigger = false;
    10.  
    11.     public GameObject textO;
    12.     public GameObject textC;
    13.  
    14.     //Animator variables
    15.     Animator animator;
    16.     bool doorOpen;
    17.     //Sound variables
    18.     public GameObject doorOpenSound;
    19.     public GameObject doorCloseSound;
    20.  
    21.  
    22.  
    23.  
    24.  
    25.  
    26.     void Start () { //what happens in the beginning of the game.
    27.         textC.SetActive (false);
    28.         textO.SetActive (false);
    29.         T_ActivatedOpen = true;
    30.         T_ActivatedClose = false;
    31.  
    32.         animator = GetComponent<Animator> ();
    33.         doorOpen = false;
    34.  
    35.  
    36.         doorCloseSound.SetActive (false);
    37.         doorOpenSound.SetActive (false);
    38.  
    39.  
    40.  
    41.    
    42.     }
    43.    
    44.  
    45.     void Update () { //The main function wich controlls how the system will work.
    46.  
    47.         if (T_ActivatedOpen == true)
    48.             T_ActivatedClose = false;
    49.  
    50.         else if (T_ActivatedClose == true)
    51.             T_ActivatedOpen = false;
    52.  
    53.         if (activateTrigger && Input.GetKeyDown (KeyCode.E)) //For some reaseon you can't have both E (open and close).
    54.             {
    55.                
    56.                 T_ActivatedOpen = false;
    57.                 T_ActivatedClose = true;
    58.                 textO.SetActive (false);
    59.                 textC.SetActive (true);
    60.                 doorOpen = true;
    61.  
    62.                 doorOpenSound.SetActive (true);
    63.                 doorCloseSound.SetActive (false);
    64.  
    65.             if (doorOpen)
    66.             {
    67.                 doorOpen = true;
    68.                 doorController ("Open");
    69.             }
    70.                
    71.             }
    72.             else if(T_ActivatedClose && activateTrigger && Input.GetKey (KeyCode.F))
    73.             {
    74.                 T_ActivatedOpen = true;
    75.                 T_ActivatedClose = false;
    76.                 textO.SetActive (true);
    77.                 textC.SetActive (false);
    78.  
    79.                 doorCloseSound.SetActive (true);
    80.                 doorOpenSound.SetActive (false);
    81.    
    82.             if (doorOpen)
    83.             {
    84.                 doorOpen = false;
    85.                 doorController ("Close");
    86.             }
    87.                
    88.             }
    89.     }
    90.  
    91.  
    92.                                                        
    93.     void OnTriggerEnter(Collider col) //If you enter the trigger this will happen.
    94.     {
    95.         if(col.gameObject.tag == "Player")
    96.         {
    97.  
    98.                 activateTrigger = true;
    99.             if((T_ActivatedOpen == true))
    100.             textO.SetActive (true);
    101.  
    102.             if((T_ActivatedClose == true))
    103.                 textC.SetActive (true);
    104.         }
    105.        
    106.     }
    107.  
    108.  
    109.     void OnTriggerExit(Collider col) //If you exit the trigger this will happen.
    110.     {
    111.         if(col.gameObject.tag == "Player")
    112.         {
    113.             textO.SetActive (false);
    114.             textC.SetActive (false);
    115.             activateTrigger = false;
    116.         }
    117.  
    118.     }
    119.  
    120.     void doorController(string direction) //Animator function.
    121.     {
    122.         animator.SetTrigger(direction);
    123.     }
    124.        
    125. }
    126.