Home > database >  Why does Unity get stuck on "Application.EnterPlayMode" with this script?
Why does Unity get stuck on "Application.EnterPlayMode" with this script?

Time:08-17

When a script is enabled, Unity will get stuck on "Application.EnterPlayMode" when trying to test the game via play mode. The only way to stop it is to kill the program via Task Manager. I have seen similar questions where the problem was an infinite loop in the script. After triple checking my code, I cannot find any loops and fear something else may be the issue (the script in question is below). If it helps, the goal of this script is to spawn an enemy periodically, currently 5 seconds. If you know of any other causes or find a loop in my script, please let me know.

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawnerScript : MonoBehaviour
{

    public GameObject enemyPrefab;

    public int spawnRate = 5;
    int timeFromLastSpawn = 0;

    // Start is called before the first frame update
    void Start()
    {
        Timer();
    }

    void Timer ()
    {
        for (timeFromLastSpawn = 0; timeFromLastSpawn < spawnRate; timeFromLastSpawn  )
        {
            Thread.Sleep(1000);
        }
        int randomYPos = new System.Random().Next(0, 5);
        SpawnNewEnemy(randomYPos);
        Timer();
    }

    void SpawnNewEnemy(float yPos)
    {
        Instantiate(enemyPrefab, new Vector2(-12, yPos), Quaternion.identity);
    }
}

CodePudding user response:

Never use Thread.Sleep for timing in Unity games (or most any program, really), as this will pause the entire game thread, not just the one script (which you probably thought it did).

In this case, you have two (basic) options. You can either use a Coroutine and WaitForSeconds:

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(Timer());
    }

    IEnumerator Timer()
    {
        Random random = new System.Random(); //reuse your random instances
        while (spawnEnemies) {
            yield new WaitForSeconds(spawnRate); //wait for spawnRate seconds
            int randomYPos = random.Next(0, 5);
            SpawnNewEnemy(randomYPos);
        }
    }

or a timer variable in your Update method:

    private float spawnRate = 5;
    private float timeSinceSpawn;

    private Random random = new System.Random(); //reuse your random instances

    void Update()
    {
        timeSinceSpawn  = Time.deltaTime;

        if (timeSinceSpawn > spawnRate) { //only spawn if we need to
            int randomYPos = random.Next(0, 5);
            SpawnNewEnemy(randomYPos);
        }
    }
  • Related