- Home /
automatic door with coroutine
Hi, I would like to make a door that moves (or simply deactivates) when clicked, then returns after about 3 seconds so that there is a short window to pass through a door. I'm too new to coding to figure out how to write a coroutine with waitforseconds to do this and the information in the manual all seems to be written for someone who understands a lot of coding terms. is there a simple script that would accomplish what I'm asking for?
The code I have currently doesn't reactivate the door, but does deactivate it on click using void OnMouseUp
My code is this:
public GameObject doorOne;
public GameObject doorTwo;
void OnMouseUp()
{
doorOne.SetActive (false);
doorTwo.SetActive (false);
}
(the model imported strangely so the door was accidentally made in two parts, and I just have a gameobject for both)
Answer by dubbreak · Jun 09, 2015 at 08:20 PM
Something along the lines of this will do:
public GameObject doorOne;
public float deactivateTime = 3.0f;
void OnMouseUp()
{
StartCoroutine(TimedDeactivate(doorOne, deactivateTime));
}
private IEnumerator TimedDeactivate(GameObject objectToDeactivate, float time)
{
objectToDeactivate.SetActive(false);
yield return new WaitForSeconds(time);
objectToDeactivate.SetActive(true);
}
Alternatively you can make a new script you can add to object, to make them objects that support timed deactivation. Then you'd have to access the object using that type (either by casting or by having the reference with that type) so you can call that method.
public class TimedDeactivatedObject : MonoBehaviour
{
public float DeactivateTime = 3.0f;
public void DeactivateForTime()
{
StartCoroutine(TimedDeactivate(this.gameObject, DeactivateTime);
}
private IEnumerator TimedDeactivate(GameObject objectToDeactivate, float time)
{
objectToDeactivate.SetActive(false);
yield return new WaitForSeconds(time);
objectToDeactivate.SetActive(true);
}
}
Then just call:
public TimeDeactivatedObject door;
void OnMouseUp()
{
door.DeactivateTime = 1.5f //or set in editor
door.DeactivateForTime();
}
i used the first suggestion you made. the only change i made was I had to set time equal to deactivateTime and deactivatedObject equal to doorOne in order for the actual activation part of the script to affect the door. thanks for the help! this was the final script:
public GameObject doorOne; public float deactivateTime = 3.0f;
void On$$anonymous$$ouseUp()
{
StartCoroutine(TimedDeactivate(doorOne, deactivateTime));
}
private IEnumerator TimedDeactivate(GameObject objectToDeactivate, float time)
{
objectToDeactivate = doorOne;
time = deactivateTime;
objectToDeactivate.SetActive(false);
yield return new WaitForSeconds(time);
objectToDeactivate.SetActive(true);
}
Answer by Cherno · Jun 09, 2015 at 10:45 PM
Here's a door script I wrote a while ago. It can be set up for automatic opening when someone is near, or only if it is activated by some other means. For testing purposes, you cna hit ENTER and the door will activate. I also supports playing sounds with a start, looped middle and end section. After a few seconds, it will close again on it's own. Note that this door workd with tha Animation component, so if you want it to move with Lerp you have to add that function yourself.
using UnityEngine;
using System.Collections;
public class Door : MonoBehaviour
{
public AudioClip startSound;
public AudioClip transitSound;
public AudioClip endSound;
private int state;//0 = closed/idle, 1 = opening, 2 = closing, 3 = open
private float openTimer;
private float closeTimer;
public float closeDelay = 5;
private bool soundPlaying;
public float autoCloseTimer;
public bool blocked;
private bool colliderDisabled;
public bool motionSensor;
public bool locked;
public GameObject key;
public GameObject button;
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Return)) {
ActivateDoor();
return;
}
if(state == 3) {
if(colliderDisabled == false) {
colliderDisabled = true;
DisableColliders();
GetComponent<Collider>().enabled = true;
}
if(blocked == false) {
autoCloseTimer += Time.deltaTime;
}
else {
autoCloseTimer = 0.0f;
}
}
else {
if(colliderDisabled == true) {
colliderDisabled = false;
EnableColliders();
}
autoCloseTimer = 0.0f;
}
if(autoCloseTimer >= closeDelay && blocked == false) {
ActivateDoor();
}
if(state == 1) {
openTimer += Time.deltaTime;
}
if(openTimer >= 1.5f) {
state = 3;
GetComponent<AudioSource>().clip = endSound;
GetComponent<AudioSource>().loop = false;
GetComponent<AudioSource>().Play();
ResetTimer();
}
if(state == 2) {
closeTimer += Time.deltaTime;
if(blocked == true) {
GetComponent<Animation>().CrossFade("door1_open", 1.0f, PlayMode.StopAll);
state = 1;
PlayTransitSound();
ResetTimer();
}
}
if(closeTimer >= 1.5f) {
state = 0;
GetComponent<AudioSource>().clip = endSound;
GetComponent<AudioSource>().loop = false;
GetComponent<AudioSource>().Play();
ResetTimer();
}
}
void OnTriggerStay() {
blocked = true;
if(motionSensor == true && state == 0) {
ActivateDoor();
}
}
void OnTriggerExit() {
blocked = false;
}
public void ActivateDoor() {
if(state == 0) {
GetComponent<Animation>().Play("door1_open", PlayMode.StopAll);
state = 1;
PlayTransitSound();
ResetTimer();
return;
}
if(state == 1) {
return;
}
if(state == 2) {
GetComponent<Animation>().CrossFade("door1_open", 1.0f, PlayMode.StopAll);
state = 1;
PlayTransitSound();
ResetTimer();
return;
}
if(state == 3) {
GetComponent<Animation>().Play("door1_close", PlayMode.StopAll);
state = 2;
PlayTransitSound();
ResetTimer();
return;
}
}
public void OpenDoor() {
GetComponent<Animation>().CrossFade("door1_open", 1.0f, PlayMode.StopAll);
state = 1;
PlayTransitSound();
ResetTimer();
}
public void CloseDoor() {
if(blocked == true) {
return;
}
GetComponent<Animation>().CrossFade("door1_close", 1.0f, PlayMode.StopAll);
state = 2;
PlayTransitSound();
ResetTimer();
}
public void LockDoor() {
locked = true;
}
public void UnlockDoor() {
locked = false;
}
void PlayTransitSound() {
GetComponent<AudioSource>().clip = startSound;
GetComponent<AudioSource>().loop = false;
GetComponent<AudioSource>().Play();
StartCoroutine(TransitLoop(GetComponent<AudioSource>().clip.length));
}
IEnumerator TransitLoop(float yieldTime) {
yield return new WaitForSeconds(yieldTime);
GetComponent<AudioSource>().clip = transitSound;
GetComponent<AudioSource>().loop = true;
GetComponent<AudioSource>().Play();
}
void ResetTimer() {
openTimer = 0.0f;
closeTimer = 0.0f;
}
void EnableColliders() {
Collider[] colliders;
colliders = GetComponentsInChildren<Collider>();
foreach (Collider c in colliders) {
c.enabled = true;
}
}
void DisableColliders() {
Collider[] colliders;
colliders = GetComponentsInChildren<Collider>();
foreach (Collider c in colliders) {
c.enabled = false;
}
}
}
Your answer
Follow this Question
Related Questions
Doing WaitForSeconds in C# 0 Answers
Can't get past WaitForSeconds in my coroutine 1 Answer
How to get precise spawn interval (C#)? 3 Answers
How can i wait seconds without a coroutine (C#)? 4 Answers
WaitForSeconds not working C# 1 Answer