- Home /
Gets stuck on WaitForSeconds
I'm having a problem with Coroutines and yield. When the ball passes the goal lines the score updates and then a new ball i supposed to be spawned after 1.5 sec. But I get stuck on yield return new WaitForSeconds(1.5f); in Pong.cs. I've read the docs but I can still not figure out whats the problem.
The score is added but no ball is spawned.
Updates:
If I comment out yield return new WaitForSeconds(1.5f); the code works, but of course doesn't wait.
I'm new to Unity and C# so don't trust my code as it was your own :)
Ball.cs attached to BallPrefab
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
private static int TOP, BOT;
private static Pong PONG;
public float maxVelocity = 3;
public float minVelocity = 0.1f;
void Awake () {
PONG = Pong.INSTANCE;
TOP = ((int)Pong.TOP.z) + 2;
BOT = ((int)Pong.BOT.z) - 2;
rigidbody.velocity = new Vector3(0, 0, -7);
}
// Update is called once per frame
void Update () {
//Make sure we stay between the MAX and MIN speed.
float totalVelocity = Vector3.Magnitude(rigidbody.velocity);
if(totalVelocity>maxVelocity) {
float tooHard = totalVelocity / maxVelocity;
rigidbody.velocity /= tooHard;
} else if (totalVelocity < minVelocity) {
float tooSlowRate = totalVelocity / minVelocity;
rigidbody.velocity /= tooSlowRate;
}
if(transform.position.z <= BOT) {
Destroy(gameObject);
StartCoroutine(PONG.Goal(1));
} else if(transform.position.z >= TOP) {
Destroy(gameObject);
StartCoroutine(PONG.Goal(2));
}
}
}
Pong.cs attached to MainCamera
using UnityEngine;
using System.Collections;
using System.Threading;
using System.Diagnostics;
public enum PongGameState { playing, won, lost };
public class Pong : MonoBehaviour {
public Transform ballPrefab;
public static Pong INSTANCE;
public static Vector3 TOP = new Vector3(10, 0, 15);
public static Vector3 BOT = new Vector3(10, 0, 5);
public static Vector3 LEFT = new Vector3(5, 0, 10);
public static Vector3 RIGHT = new Vector3(15, 0, 10);
private PongGameState gameState;
void Awake() {
INSTANCE = this;
gameState = PongGameState.playing;
Time.timeScale = 1.0f;
SpawnBall();
}
private void SpawnBall() {
print("spawnball");
Instantiate(ballPrefab, new Vector3(10.0f, 0.0f, 10.0f), Quaternion.identity);
}
public IEnumerator Goal(int player){
print("in goal");
Scores.AddPoint(player);
yield return new WaitForSeconds(1.5f);
print("in goal");
SpawnBall();
}
}
Since I can't comment on the answer I'll comment here. @almo, you would be correct if i was writing in Javascript
Wow. Looks right to me. That's goofy. I'll stay subscribed because I'd like to know the answer to this, too.
Still can't comment on your answers (Can someone vote up my Q so I get karma to do that?). @cfbevan: Didn't work but thanks for the link, it's was some good info. If I comment out the WaitForSeconds(), the code works but it doesn't wait.
Answer by Mike 3 · Jul 27, 2011 at 03:27 PM
You're destroying the object which starts the coroutine, stopping it from running after the wait
Change this line (both times):
StartCoroutine(PONG.Goal(1));
to
PONG.StartCoroutine(PONG.Goal(1));
So that the coroutine is run on the same object it's interested in
Edit, to make it more obvious why:
When you start a coroutine, the monobehaviour it's run from is "attached" to it in a way that when the monobehaviour is disabled or destroyed, the coroutine will stop running
Your answer