简体   繁体   English

Unity 3D - 如何在僵尸全部死后重生?

[英]Unity 3D - How to respawn zombies after their all dead?

I'm trying to make a simple 3D fps.我正在尝试制作一个简单的 3D fps。 right now, I'm working on randomly spawning zombies.现在,我正在研究随机生成僵尸。 The only problem is that after the zombies spawn and I shoot them, they don't respawn.唯一的问题是,在僵尸生成并且我射击它们之后,它们不会重生。 How can I make it so that after 10 seconds for example, another set of zombies appear?例如,我怎样才能让它在 10 秒后出现另一组僵尸?

Here is my zombie spawner script:这是我的僵尸生成器脚本:

using System.Collections;
using UnityEngine;

public class GenerateEnemies : MonoBehaviour
{
public GameObject theEnemy;
public float xPos;
public float zPos;
public int enemyCount;

// Start is called before the first frame update
void Start()
{
    StartCoroutine(EnemyDrop1());
    StartCoroutine(EnemyDrop2());
    StartCoroutine(EnemyDrop3());
    StartCoroutine(EnemyDrop4());
}

IEnumerator EnemyDrop1()
{
    while(enemyCount < 5)
    {
        xPos = Random.Range(-22, -130);
        zPos = Random.Range(135, -135);
        Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
        yield return new WaitForSeconds(0.1f);
        enemyCount += 1;
    }
}

IEnumerator EnemyDrop2()
{
    while (enemyCount < 10)
    {
        xPos = Random.Range(-23, 134);
        zPos = Random.Range(-75, -135);
        Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
        yield return new WaitForSeconds(0.1f);
        enemyCount += 1;
    }
}

IEnumerator EnemyDrop3()
{
    while (enemyCount < 15)
    {
        xPos = Random.Range(30, 130);
        zPos = Random.Range(-75, 135);
        Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
        yield return new WaitForSeconds(0.1f);
        enemyCount += 1;
    }
}

IEnumerator EnemyDrop4()
{
    while (enemyCount < 20)
    {
        xPos = Random.Range(-22, -130);
        zPos = Random.Range(135, -135);
        Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
        yield return new WaitForSeconds(0.1f);
        enemyCount += 1;
    }
}
}

by the way, I did the script this way so that the zombies don't spawn too close to the player.顺便说一句,我是这样编写脚本的,这样僵尸就不会离玩家太近。

I'm new at unity, so if you do have an answer, please explain it.我是统一的新手,所以如果你有答案,请解释一下。 Thanks:)谢谢:)

Why zombies won't re-spawn为什么僵尸不会重生

There are a couple of potential reasons on why your zombies stop respawning:僵尸停止重生的原因有两个:

  1. The code sample you provided doesn't subtract anything from enemyCount .您提供的代码示例不会从enemyCount中减去任何内容。 Assuming that is also the case everywhere else, it could be the culprit in the issue.假设其他地方也是如此,它可能是问题的罪魁祸首。
  2. The Coroutine methods that contain the while loops, run while a set condition is true.包含 while 循环的协程方法在设置条件为真时运行。 That means that your script will stop spawning enemies altogether as soon as a certain number is reached.这意味着一旦达到一定数量,您的脚本将完全停止生成敌人。

I'm gonna assume the 2. point is true in this case.在这种情况下,我将假设 2. 点是正确的。


Solution解决方案

A potential solution I would offer is to make the while loops last either forever or using a different condition and put the previously used condition into an if statement.我将提供的一个潜在解决方案是使 while 循环永远持续或使用不同的条件,并将先前使用的条件放入 if 语句中。 That will make the loops remain functional but skip over the step where a zombie is spawned when there are too many of them.这将使循环保持功能,但当它们太多时跳过生成僵尸的步骤。

Here's a modified version of your code:这是您的代码的修改版本:

using System.Collections;
using UnityEngine;

public class GenerateEnemies : MonoBehaviour
{
    public GameObject theEnemy;
    public float xPos;
    public float zPos;
    public int enemyCount;

    private void Start()
    {
        StartCoroutine(EnemyDrop1());
        StartCoroutine(EnemyDrop2());
        StartCoroutine(EnemyDrop3());
        StartCoroutine(EnemyDrop4());
    }

    private IEnumerator EnemyDrop1()
    {
        while (true)
        {
            if (enemyCount >= 5)
            {
                yield return new WaitForSeconds(0.1f);
                continue;
            }

            xPos = Random.Range(-22, -130);
            zPos = Random.Range(135, -135);
            Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
            yield return new WaitForSeconds(0.1f);
            enemyCount += 1;
        }
    }

    private IEnumerator EnemyDrop2()
    {
        while (true)
        {
            if (enemyCount >= 10)
            {
                yield return new WaitForSeconds(0.1f);
                continue;
            }

            xPos = Random.Range(-23, 134);
            zPos = Random.Range(-75, -135);
            Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
            yield return new WaitForSeconds(0.1f);
            enemyCount += 1;
        }
    }

    private IEnumerator EnemyDrop3()
    {
        while (true)
        {
            if (enemyCount >= 15)
            {
                yield return new WaitForSeconds(0.1f);
                continue;
            }

            xPos = Random.Range(30, 130);
            zPos = Random.Range(-75, 135);
            Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
            yield return new WaitForSeconds(0.1f);
            enemyCount += 1;
        }
    }

    private IEnumerator EnemyDrop4()
    {
        while (true)
        {
            if (enemyCount >= 20)
            {
                yield return new WaitForSeconds(0.1f);
                continue;
            }

            xPos = Random.Range(-22, -130);
            zPos = Random.Range(135, -135);
            Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
            yield return new WaitForSeconds(0.1f);
            enemyCount += 1;
        }
    }
}

Here's a slightly refactored version of the same code:这是相同代码的稍微重构的版本:

using System.Collections;
using UnityEngine;

public class GenerateEnemies : MonoBehaviour
{
    public GameObject theEnemy;
    public float xPos;
    public float zPos;
    public int enemyCount;

    private void Start()
    {
        StartCoroutine(EnemyDrop(5, -130f, -22f, -135f, 135f));
        StartCoroutine(EnemyDrop(10, -23f, 134f, -135f, -75f));
        StartCoroutine(EnemyDrop(15, 30f, 130f, -75f, 135f));
        StartCoroutine(EnemyDrop(20, -130f, -22f, -135f, 135f));
    }

    private IEnumerator EnemyDrop(
        int maxEnemyCount,
        float minPositionX,
        float maxPositionX,
        float minPositionZ,
        float maxPositionZ)
    {
        while (true)
        {
            if (enemyCount >= maxEnemyCount)
            {
                yield return new WaitForSeconds(0.1f);
                continue;
            }

            xPos = Random.Range(minPositionX, maxPositionX);
            zPos = Random.Range(minPositionZ, maxPositionZ);
            Instantiate(theEnemy, new Vector3(xPos, 1, zPos), Quaternion.identity);
            enemyCount += 1;

            yield return new WaitForSeconds(0.1f);
        }
    }
}

Extra note额外说明

If you intend to write a solution where you want to gradually spawn let's say exactly 10 zombies and then stop until there are no zombies again, I'll leave you with the following code sample as a hint (I'll leave the full solution up to you):如果您打算编写一个要逐渐生成的解决方案,假设正好有 10 个僵尸,然后停止,直到不再有僵尸,我将给您留下以下代码示例作为提示(我将保留完整的解决方案给你):

private IEnumerator KeepDroppingEnemies()
{
    while (true)
    {
        yield return new WaitUntil(() => enemyCount == 0);
        yield return DropEnemies(10);
    }
}

private IEnumerator DropEnemies(int numberOfEnemies)
{
    for (int i = 0; i < numberOfEnemies; i++)
    {
        // Spawn an enemy

        yield return new WaitForSeconds(0.1f);
    }
}

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

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