VR的100天的第23天:在Unity中为敌人创建产卵系统

在这里,我们又回到了Unity开发的第二天! 今天在第23天,我们将学习如何生成敌方波。

目前,这款游戏并不具有挑战性,我们只有一个敌人!

今天,我们将通过产生大量敌人击败敌人来解决此问题,从而使游戏难以生存!

这将是一个巨大的变化,需要几天的时间,所以让我们开始吧!

如果要从Unity Survival Shooter教程中回想起要生成敌人,则需要创建一个SpawnManager类来创建敌人的新实例。

在我们的Spawn Manager中,除了其他要添加的内容外,我们需要提供的主要内容是:

  • 我们将产生敌人的位置
  • 我们想要产生的敌人

但是,作为一个挑战,而不是像生存射击游戏那样游戏会继续下去,我们将产生数量有限的敌人,这样我们才能获胜。

波动系统涉及很多工作,我从Unity的敌人Spawner示例中借鉴了很多想法。

我们要做的第一件事是创建一个新的Empty Game Object ,我们将其称为EnemyManager 。 我们将使它成为我们GameManager的子代。

接下来,我们将为新游戏对象创建一个新脚本,我们将其称为EnemyManager

我们将与经理一起做几件事:

  • 跟踪我们所处的浪潮
  • 跟踪我们在一波中击败了多少敌人
  • 跟踪每波有多少个敌人

通过跟踪敌人和海浪的数量,我们可以判断何时移至下一波以及我们是否获胜。

这是EnemyManager.cs的初始代码

 使用System.Collections; 
使用UnityEngine;
[System.Serializable]
公共类Wave
{
public int EnemiesPerWave;
公共GameObject敌人;
}
公共类SpawnManager:MonoBehaviour
{
公共Wave [] Waves; //每波保存信息的类
public Transform [] SpawnPoints;
public float TimeBetweenEnemies = 2f;
private int _totalEnemiesInCurrentWave;
private int _enemiesInWaveLeft;
private int _spawnedEnemies;
private int _currentWave;
private int _totalWaves;
无效开始()
{
_currentWave = -1; //避免偏离1
_totalWaves = Waves.Length-1; //调整,因为我们使用0索引
StartNextWave();
}
void StartNextWave()
{
_currentWave ++;
//赢
如果(_currentWave> _totalWaves)
{
返回;
}
_totalEnemiesInCurrentWave = Waves [_currentWave] .EnemiesPerWave;
_enemiesInWaveLeft = 0;
_spawnedEnemies = 0;
StartCoroutine(SpawnEnemies());
}
//协程产生我们所有的敌人
IEnumerator SpawnEnemies()
{
GameObject敌人= Waves [_currentWave]。敌人;
而(_spawnedEnemies <_totalEnemiesInCurrentWave)
{
_spawnedEnemies ++;
_enemiesInWaveLeft ++;
int spawnPointIndex = Random.Range(0,SpawnPoints.Length); //在随机选择的生成点的位置和旋转位置创建敌人预制的实例。
实例化(敌人,SpawnPoints [spawnPointIndex] .position,SpawnPoints [spawnPointIndex] .rotation);
产生返回新的WaitForSeconds(TimeBetweenEnemies);
}
yield return null;
}

//被敌人击败时召唤
公共无效EnemyDefeated()
{
_enemiesInWaveLeft--;

//一旦产生并击败所有敌人,我们便开始下一波
如果(_enemiesInWaveLeft == 0 && _spawnedEnemies == _totalEnemiesInCurrentWave)
{
StartNextWave();
}
}
}

现在要花很多钱,这就是为什么我添加注释的原因,但是,这是这段代码的贯穿过程。

在讨论变量之前,我想介绍Wave类。

Wave是一个容器,可以容纳我们将要面对的每个wave的数据。

如果您还记得Space Shooter教程,我们做了类似的事情。 我们创建了一个新类来保存信息,并将其设置为可序列化,以便Unity知道如何在编辑器中显示它。

最初,我只是将其每个内容传递给我们的SpawnManager,但这很容易导致我们混淆每个波产生多少敌人以及哪些敌人。

对于我们的公共变量,我们有:

  • WavesWave类的数组,我们创建了Wave类的一种简单方法,以便我们访问每个wave的数据
  • SpawnPoints —我们将实例化敌人的一系列位置
  • TimeBetweenEnemies —在产生下一个敌人之前的等待时间

为了让我们的私有变量能够跟踪敌人,我们具有:

  • _totalEnemiesInCurrentWave —自我说明
  • _enemiesInWaveLeft —仍在波浪中存活的敌人数量
  • _spawnedEnemies —自我说明

我们还跟踪我们所处的浪潮:

  • _currentWave —自我说明
  • _totalWaves —自我说明

既然我们知道了所使用的变量,我们就可以遍历其余的代码。

  1. Start()中 ,将所有变量初始化为0。请注意,我们将_currentWave设置为-1,而_totalWaves是数组的长度—1。对于那些不熟悉的人,所有这些都是因为,在基于0的数组索引中工作(意味着所有内容均从0而不是1开始)。
  2. Start()中,我们还调用StartNextWave(),该代码处理清除波时发生的情况。 我们增加_currentWave并假设我们还没有完成游戏,我们将设置下一波需要遇到的敌人并调用SpawnEnemies()
  3. SpawnEnemies()是我们用来创建敌人的协程。 该功能将根据我们设置的随机生成点之一生成波浪的敌人。 该代码将等待2秒钟,然后再生成下一个敌人,这样我们就不会立即向所有敌人挥手挥手。
  4. 最后,我们有公共EnemyDefeated() ,这意味着该函数是从其他地方调用的。 在这种情况下,我们的敌人遇难时会称呼它。 然后,我们将减少敌人的计数器,如果我们在一波中击败了所有敌人,我们将调用StartNextWave()

这是代码的基本摘要。 那还不错,现在呢? 对?!

现在我们已经启动并运行了脚本,最后要做的就是设置Wave并创建Spawn Points

现在,让我们为SpawnManager产生2个波浪来创建我们的骑士敌人。

我们的Wave类需要提供两件事:

  • 骑士游戏对象
  • 波浪中会产生多少敌人

让我们首先设置骑士游戏对象。

我们可以将骑士从等级制度中拖放到现场,一切都会好起来的。 但是,正确的方法是首先为我们的骑士制作一个预制件

我们可以认为预制是游戏对象的模板,我们可以将其拖动并共享到不同的场景和游戏。 在我们的情况下,我们也可以像在此一样实例化它们。

主要的好处是,如果您要更改预制件,则无论何时我们需要更改某些东西,我们都可以更改预制件,而任何从代码实例化该预制件的东西也将得到更改。

我们要做的第一件事是:

  1. 在我们的Assets文件夹中创建一个名为Prefabs的文件夹
  2. 通过将我们的Knight游戏对象拖到Prefabs Note中来创建我们的预制件,在这个示例中,我们的Knight已经是一个预制件,但是没关系,我们已经对其进行了一些更改,因此让我们从中制作另一个预制件。

附带说明:我们可以从层次结构中删除 Knight游戏对象。 他为我们提供了很好的服务,但我们不再需要他的服务。

现在我们有了所需的一切,就可以开始创建波浪了。

回到我们的SpawnManger脚本中,展开Waves并将Size设置为2,以便我们可以创建新的wave。

外观如下:

现在我们已经有了wave系统的设置,我们需要创建派生点。

就像生存射击游戏一样,我们需要添加一些游戏对象,并将其用作生成敌人的位置。

让我们开始吧!

创建3个游戏对象:我称它们为SpawnPoint1SpawnPoint3。 我将它们作为SpawnManager的子 ,但是,将它们放置在什么位置并不重要。

现在,我们看不到SpawnPoints在游戏中的位置,但是我们可以向其添加标签以查看对象的位置。

我们只想将Spawn点设置在3个房屋中。

这是我的排名值,您的可能有所不同:

SpawnPoint1:98、0、118

SpawinPoint2:72、0、89

SpawnPoint3:106、0、80

最后,回到我们的SpawnManager并添加我们的SpawnPoints

展开Spawn Points ,然后将其Size更改为3,然后将SpawnPoints拖动到空白游戏位置。

有了所有这些之后,如果我们玩游戏,我们现在应该有多个敌人向我们袭来。

生成系统还没有完全完成,但是我们为产生敌人奠定了基础。

我们仍然需要实施产生新敌人并最终创造胜利条件的逻辑。 我们将从明天的24天开始实施这些功能!

话虽这么说,晚上好!

资料来源:第23天

访问Unity VR开发的100天主页。

访问我们的主页