Yield WaitForSeconds isn't doing what I expect. Help please.

Hi, so here’s my code below. I’m making a blackjack game. At about 20% through the deck, it plays the yellow card, which means once this hand is done, all the cards will be reshuffled. Anyway, what I want is for it to deal the yellow card, then the yellow card moves up to the top corner, and it continues on dealing the rest of the hand. However, what’s happening is that it’s dealing the yellow card and the card after at the same time. Or fast enough that it seems like it’s at the same time.

So right now I put a hold for 5 seconds after the yellow card is dealt, just so i can see if it’s working. The debug text does work. It shows the before text, then the after text 5 seconds later. But I can’t seem to get it to wait the 5 seconds to deal the next card. Anyone see something I’m doing wrong? The code works exactly how I want it to right now, except I can’t seem to make the pause happen.

function Yellow()
{
	yellowCard = Instantiate(yellow, dealYellowCard.transform.position, dealYellowCard.transform.rotation);
	yellowCard.name = "yellow";
	yield WaitForSeconds(1);
	yellowCard.transform.position = holdYellowCard.transform.position;
	
}

function HoldYellow()
{
	print("Before 5 Seconds");
	yield WaitForSeconds(5);
	print("After 5 Seconds");
}

function DealCard() : GameObject
{
	if(yellowPlayed == true  dealReady == true)
	{
		ResetDeck();
	}
	
	totalCards = numDecks * 52;
	twentyPercent = totalCards * 0.2;
	
	if(cards.Count == twentyPercent  yellowPlayed == false)
	{
		Yellow();
		HoldYellow();
		yellowPlayed = true;
		card = Random.Range(0, cards.Count);
		go = GameObject.Instantiate(cards[card]) as GameObject;
		cards.RemoveAt(card);
		return go;	
	}
	else
	{
		card = Random.Range(0, cards.Count);
		go = GameObject.Instantiate(cards[card]) as GameObject;
		cards.RemoveAt(card);
		return go;
	}
}

I’m not a UnityScript/JavaScript guy, but I got two comments.

  1. In C# we have to run StartCoroutine() for WaitForSeconds() to work. I’m not entirely sure if this is the case in UnityScript.
  2. When you start the coroutine, the next line runs immediately, while the function that is the coroutine will wait.
if (cards.Count == twentyPercent  yellowPlayed == false)
{
  Yellow();
  // Run StartCoroutine to actually start a coroutine.
  // I'M NOT A JAVASCRIPT GUY. Not sure if this is right.
  StartCoroutine(HoldYellow());
     
  // I do know this part.
  // This line will occur immediately! There will be no wait.
  // The WaitForSeconds happens in HoldYellow(),
  // There is no wait in this function.
  yellowPlayed = true;
  // ...
}

You don’t need StartCoroutine in Javascript; it’s implicit. If you want to wait for the HoldYellow coroutine to finish before running more code, use “yield HoldYellow()”. However you will have to change your logic for the DealCard function, since coroutines return IEnumerator, they can’t return GameObject.

–Eric

Ok thanks. I didn’t realize I actually had to put the work yield in front of the function. That’s handy to learn.

I’ll have to look into IEnumerator, I’m not seeing anything about it in the scripting reference. I’m pretty new to this, so I suppose this will be my next thing to figure out.

Thanks guys!

In UnityScript, you don’t have to use IEnumerator, that’s a feature (or burden) only implemented in C#.

Unityscript uses IEnumerator same as C#; whether you actually write it out as the return type for a function is optional. If you make a function a coroutine, then IEnumerator is inferred as the return type.

function Wait () {
    yield WaitForSeconds(1);
}

function Wait () : IEnumerator { // same thing
    yield WaitForSeconds(1);
}

–Eric