Coroutine different behaviour when called from another script

I am quite new with game dev, specially with unity. In order to understand how it works, I decided to start small with a pong game.

I have a Ball script, which in the Update() method move the ball depending to the speed, and if a player score, it increment a score field and reset the ball to the center (and stop the ball for 2 seconds) trough a coroutine function.

Ball script:

public class Ball : MonoBehaviour
{
[SerializeField]
float speed;
int isMoving = 1;
Vector2 direction;
Vector2 startPosition;

// Start is called before the first frame update
void Start()
{
direction = Vector2.one.normalized;
radius = transform.localScale.x / 2; // half the width
startPosition = new Vector2(transform.position.x, transform.position.y);
}

// Update is called once per frame
void Update()
{
transform.Translate(direction * speed * isMoving * Time.deltaTime);

if (transform.position.y < GameManager.bottomLeft.y + radius && direction.y < 0) {
direction.y = -direction.y;
}
if (transform.position.y > GameManager.topRight.y - radius && direction.y > 0) {
direction.y = -direction.y;
}

// Ball go in any goal
if (transform.position.x < GameManager.bottomLeft.x + radius && direction.x < 0) {
StartCoroutine( Reset() );
}
if (transform.position.x > GameManager.topRight.x - radius && direction.x > 0) {
StartCoroutine( Reset() );
}
}

IEnumerator Reset() {
isMoving = 0;
transform.position = startPosition;

yield return new WaitForSeconds(2);

isMoving = 1;
}
}


This works as expected! The score is incremented, the ball go back to the center, wait for 2 seconds and start to move again. However, now I want to call the Ball Reset() method trough my GameManager (because I want to code some logics inside the GameManager).

So here are my modifications:

Ball script: (remove Reset() calls and update Reset() method to public)

public class Ball : MonoBehaviour
{
...

// Update is called once per frame
void Update()
{
...

// Ball go in any goal
if (transform.position.x < GameManager.bottomLeft.x + radius && direction.x < 0) {
}
if (transform.position.x > GameManager.topRight.x - radius && direction.x > 0) {
}
}

public IEnumerator Reset() {
isMoving = 0;
transform.position = startPosition;

yield return new WaitForSeconds(2);

isMoving = 1;
}


GameManager script:

public class GameManager : MonoBehaviour
{

public Ball ball;

...

void Start()
{
...

// Create ball
Instantiate (ball);

}

public void addScorePlayer(string player) {

if (player == "p1") {
score1 += 1;
score1Text.text = score1.ToString();
}
else if (player == "p2") {
score2 += 1;
score2Text.text = score2.ToString();
}

StartCoroutine( ball.Reset() );
}


This doesn't work for some reason. The ball don't come back to the center, and the score increment infinitely.

I have tried many things and I have figured out that the behaviour is the same as running the Reset() method trough the Ball script without the StartCoroutine.

So it seems that the Coroutine don't work properly if called trough the GameManager ? I have also printed some logs into my console in the Ball.Reset() method, and the method is being called, so I don't understand why the ball don't go back to the center.

(Link to my public github repository https://github.com/Sewake/Unity2D-Pong)

• Do you observe any errors in your console log when running with this code? – DMGregory Jun 1 at 20:49
• No there is no errors in my console, only prints that I have wrote into my Ball.Reset() method :/ – Sewake Jun 1 at 20:54