- Home /
Why is StartCoroutine being ignored?
I created a door script. It's supposed to open the door, wait five seconds and then close. The opening and closing is done with animations.
Here's the problematic part of the code:
IEnumerator DoorTime()
{
Time.timeScale = 1;
yield return new WaitForSeconds (DoorTimer);
}
void changeDoorState()
{
theDoor.animation.CrossFade("Open");
//theDoor.audio.PlayOneShot();
doorIsClosed = false;
StartCoroutine(DoorTime());
theDoor.animation.CrossFade("Close");
//theDoor.audio.PlayOneShot();
doorIsClosed = true;
}
and here's the full code:
using UnityEngine;
using System.Collections;
public class DoorLogic : MonoBehaviour {
public Transform theDoor;
public GameObject DoorSideA;
public GameObject DoorSideB;
public GameObject RoomA;
public GameObject RoomB;
static float DoorTimer = 5.0f;
private bool doorIsClosed = true;
private bool drawGUI = false;
void OnTriggerEnter(Collider theCollider)
{
if(theCollider.tag == "Player")
{
drawGUI = true;
}
}
void OnTriggerExit(Collider theCollider)
{
if(theCollider.tag == "Player")
{
drawGUI = false;
}
}
void OnGUI()
{
if (drawGUI == true)
{
GUI.Box( new Rect(Screen.width/2-51,200,102,22),"Press 'E' to Open");
}
}
// Update is called once per frame
void Update ()
{
if (drawGUI == true && Input.GetKeyDown( KeyCode.E))
{
changeDoorState();
}
}
IEnumerator DoorTime()
{
Time.timeScale = 1;
yield return new WaitForSeconds (DoorTimer);
}
void changeDoorState()
{
theDoor.animation.CrossFade("Open");
//theDoor.audio.PlayOneShot();
doorIsClosed = false;
StartCoroutine(DoorTime());
theDoor.animation.CrossFade("Close");
//theDoor.audio.PlayOneShot();
doorIsClosed = true;
}
}
please help
Answer by robertbu · Nov 30, 2013 at 10:07 PM
When you hit the yield on line 51 of the second script DoorTime() returns immediately. One way to fix your code, is to make 'changeDoorState' your coroutine:
IEnumerator changeDoorState()
{
theDoor.animation.CrossFade("Open");
//theDoor.audio.PlayOneShot();
doorIsClosed = false;
Time.timeScale = 1;
yield return new WaitForSeconds (DoorTimer);
theDoor.animation.CrossFade("Close");
//theDoor.audio.PlayOneShot();
doorIsClosed = true;
}
Then on line 44 you would start the coroutine rather than calling the function.
Also, because the animation time of the door is playing while you're counting down, you're not getting a full 5 seconds (or whatever DoorTimer is set to). You may consider adding this line of code after setting doorIsClosed to false (line 7 in code above at time of post):
while (theDoor.animation.isPlaying)
yield return null;
This will ensure that your door is fully open for the amount of time that you intend, regardless of animation changes (lengthening or shortening of animation duration by an artist).
thank you, that solved the problem, I'll refer to the answers more often
Answer by MarkFinn · Nov 30, 2013 at 10:06 PM
When you yield from the co-routine, processing carries right on on the next line (After the StartCoroutine call). Only the code after the yield, within the coroutine itself waits for the timeout.
Move
theDoor.animation.CrossFade("Close");
//theDoor.audio.PlayOneShot();
doorIsClosed = true;
inside the co-routine, placing it after the yield.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Simple OnGui does not work 1 Answer
Camera Follow for top down 2d shooter game 2 Answers
Turret Rotation Not correct 0 Answers