- Home /
yield return waitforseconds not waiting?
I have a script which fires a coroutine on start which activates necessary items in my level. This also calls an animation IEnumerator to phase the ui animation in and out. However, there is a lag when unity is playing an animation right away, so I wanted to write in a wait for seconds to let the editor initialize then run my animation coroutine. the script looks something like this:
start(){
startCoroutine(beginCourse());
}
IEnumerator beginCourse(){
yield return new waitForSeconds(2); //waits
yield return startCoroutine(levelBeginAnimation()); /fires opening animations
}
My problem is that the script seems to start the waitfor seconds, then starts the level begin animation coroutine, but the thing is that the wait for seconds doesnt yield. I've tried this in my code with print statements as well to be certain. Is there something I'm doing wrong here?
EDIT: actual code posting that I'm using with only pertaining code :
CoursePrefs.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoursePrefs : MonoBehaviour {
//public string courseName;
//public int currentHole = 0; //0 based hole index
// public HolePrefs[] courseHoles;
//public zoomTouch zoomFocus;
//public CameraPin pin;
//public GameObject testgui;
public UIManager _UIManager;
private void Start()
{
//makes sure zoom is at max first.
//Camera.main.orthographicSize = zoomFocus.maxZoom;
StartCoroutine(beginCourse());
}
IEnumerator beginCourse() {
yield return new WaitForSeconds(2);
yield return StartCoroutine(_UIManager.transitionAnimation());
//wait for these to finish then do this stuff;
//getCurrentHole().thisStartGreen.GetComponent<PlaceGolfBall>().enabled = true;
//pin.golfball = getCurrentHole().thisStartGreen;
//pin.isFollowing = true;
//zoomFocus.canZoom = true;
}
}
UIManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager : MonoBehaviour {
//the transitional UI that plays between holes to notify which hole is currently being played
public GameObject transition_holeNum;
public GameObject transition_frontNine;
public GameObject transition_backNine;
//Menus that play when the hole is made
public GameObject menuEndHole;
//Pause Menu
public GameObject menuPauseScreen;
//Controls the transitional UI. Hangtime is how long the menu stays between states before conitnuing the swipe out.
public IEnumerator transitionAnimation(float hangTime = 2) {
yield return StartCoroutine(transitionSwipeIn());
yield return new WaitForSeconds(hangTime);
yield return StartCoroutine(transitionSwipeOut());
}
//Controls the swipe in. offsetTime is the time between when the last animation began and the next one starts of the 3 panes.
public IEnumerator transitionSwipeIn(float offsetTime = 0.25f) {
if (transition_holeNum != null) {
transition_holeNum.GetComponent<UIController>().Show();
}
if (transition_frontNine != null) {
yield return new WaitForSeconds(offsetTime);
//start swipe in
}
if (transition_backNine != null) {
yield return new WaitForSeconds(offsetTime);
//start swipe in
}
//think about yielding a wait for seconds for how long it takes the bar to reach its destination so the animation fully completes before exiting the coroutine.
}
//Controls the swipe out
public IEnumerator transitionSwipeOut(float offsetTime = 1)
{
if (transition_holeNum != null)
{
transition_holeNum.GetComponent<UIController>().Hide();
}
if (transition_frontNine != null)
{
yield return new WaitForSeconds(offsetTime);
//start swipe out
}
if (transition_backNine != null)
{
yield return new WaitForSeconds(offsetTime);
//start swipe out
}
}
}
This... doesn't make sense. I already dislike coroutines, but this makes even less since than using a coroutine in the first place. If all you want is to start the level in 2 seconds you can just do something like
void Start()
{
Invoke("BeginLevel", 2.0f);
}
void BeginLevel()
{
//Begin Level code
}
Please post the actual code you're using - what you've written wouldn't even compile.
But @RobAnthem is correct - it's unclear why you aren't just using Invoke() in this case.
I've updated the code with pertaining code from the actual scripts
Answer by jayaluru · Jun 13, 2017 at 02:25 AM
I have a similar situation, where the call of 'StartCoroutine (waitseconds()); ' works fine but the unity does not wait for the specified time.
IEnumerator waitseconds()
{
yield return new WaitForSecondsRealtime(4);
Debug.Log("hey i waited 4 secs of my life");
}
// Update is called once per frame
void Update () {
Debug.Log("hello can u wait");
StartCoroutine(waitseconds());
Debug.Log("its me i waited");
}
The comments work fine suggesting that the call was made successfully but unity does not wait. Can anyone of you help me out??
it wont wait because its in an update, take that start couroutine out the update and put it in void start and it will wait. or throw it where you want to call it from
Answer by ankitdave · Jun 13, 2017 at 07:15 AM
Hi @jayaluru may be it works for you
public bool waitbool=false;
IEnumerator waitseconds()
{
yield return new WaitForSecondsRealtime(4);
Debug.Log("hey i waited 4 secs of my life");
waitbool = true;
}
// Update is called once per frame
void Update()
{
Debug.Log("hello can u wait");
StartCoroutine(waitseconds());
if (waitbool == true)
{
Debug.Log("its me i waited");
}
}
Answer by corriedotdev · Aug 06, 2018 at 06:15 PM
They are both being executed concurrently. You need to finish one coroutine then call the other, not line by line. Let the wait for seconds yield then start your coroutine.
void Start(){
StartCoroutine(beginCourse());
}
IEnumerator beginCourse() {
Debug.Log("waiting..");
yield return new WaitForSeconds(2); //waits
StartCoroutine(animateblah()); // fires opening animations
}
private IEnumerator animateblah() {
Debug.Log("Animating");
yield return null;
}
This will work.
You are doing exactly the same as the OP. He also waits for the nested coroutine to finish which is pretty pointless since nothing else is happening inside the coroutine after the nested one. However this doesn't change anything. His original code does work just fine. He most likely has a different problem. Either the initial lag is already 2 seconds or something else is going on he didn't show us.
I tested this and it works. Youre not yielding a cooroutine that doesnt require it in the begin