简体   繁体   English

按下播放按钮时 Unity 冻结

[英]Unity freeze when play button is pressed

I am learning Unity through an udemy course.我正在通过 udemy 课程学习 Unity。

Now I am stuck at a point where unity screen freezes when I hit the play button.现在,当我点击播放按钮时,我被困在统一屏幕冻结的地方。 It happens in the spawn manager for the random positioned enemies and powerups the IEnumerator for enemy works perfectly, but as soon as I add the same for the powerup, and hit the play button, it freezes.它发生在随机定位的敌人的生成管理器中,并且敌人的IEnumerator可以完美地工作,但是一旦我为通电添加相同的内容并点击播放按钮,它就会冻结。

When I comment out the powerup section in the spawn manager, and restart unity, it works perfectly.当我在生成管理器中注释掉 powerup 部分并重新启动 unity 时,它可以完美运行。

What should I do for my powerup spawn to work?我应该怎么做才能让我的加电生成器工作?

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

public class SpawnManager : MonoBehaviour
{
    [SerializeField]
    private GameObject _enemyShipPrefab;
    [SerializeField]
    private GameObject[] powerup;

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

    public IEnumerator EnemySpawnRoutine()
    {
        while(true)
        {
            float enemyPositionX = Random.Range(-8.34f, 8.34f);
            Instantiate(_enemyShipPrefab, new Vector3(enemyPositionX, 6.39f, 0), Quaternion.identity);
            yield return new WaitForSeconds(5.0f);
        }
    }

    public IEnumerator PowerupSpawnRoutine()
    {
        while(true)
        {
            // float powerupPositionX = Random.Range(-8.622f, 8.622f);
            int randomPowerup = Random.Range(0, 3);
            Instantiate(powerup[randomPowerup], new Vector3(Random.Range(-8.622f, 8.622f), 4.5f, 0), Quaternion.identity);
        }
    }
}

In your PowerupSpawnRoutine the while(true) is always going to run as its an infinite loop.在您的PowerupSpawnRoutine中, while(true)始终会作为无限循环运行。 You don't yield anywhere inside it.你不会yield它里面的任何地方。

You should add a delay in your PowerupSpawnRoutine as well.您还应该在PowerupSpawnRoutine中添加延迟。

public IEnumerator PowerupSpawnRoutine()
{
    while(true)
    {
        // float powerupPositionX = Random.Range(-8.622f, 8.622f);
        int randomPowerup = Random.Range(0, 3);
        Instantiate(powerup[randomPowerup], new Vector3(Random.Range(-8.622f, 8.622f), 4.5f, 0), Quaternion.identity);

        // this e.g. will spawn powerup after every 5 seconds.
        yield return new WaitForSeconds(5.0f); 
    }
}

As already mentioned in by Muhammad Farhan Aqeel you are not yield ing anywhere inside of the while(true) loop in PowerupSpawnRoutine .正如Muhammad Farhan Aqeel已经提到的那样,您在PowerupSpawnRoutinewhile(true)循环内的任何地方都没有yield


However, as complete alternative here instead of using Coroutines at all you could also use InvokeRepeating in your use case:但是,作为这里的完整替代方案,您也可以在您的用例中使用InvokeRepeating ,而不是使用 Coroutines:

[SerializeField] private float enemySpawnDelay = 5f;
[SerializeField] private float powerupSpawnDelay = 5f;

// Start is called before the first frame update
void Start()
{
    // The first parameter is the initial delay so 0 makes the first call
    // immediately.
    // The second parameter is the repeating delay
    InvokeRepeating(nameof(EnemySpawnRoutine), 0f, enemySpawnDelay);
    InvokeRepeating(nameof(PowerupSpawnRoutine), 0f, powerupSpawnDelay);
}

private void EnemySpawnRoutine()
{
    float enemyPositionX = Random.Range(-8.34f, 8.34f);
    Instantiate(_enemyShipPrefab, new Vector3(enemyPositionX, 6.39f, 0), Quaternion.identity);
}

private void PowerupSpawnRoutine()
{
    // when getting random indices use the actual length of the array to be more
    // flexible and secure against errors
    int randomPowerup = Random.Range(0, powerup.Length);
    Instantiate(powerup[randomPowerup], new Vector3(Random.Range(-8.622f, 8.622f), 4.5f, 0), Quaternion.identity);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM