游戏开发小结——创建wave系统
2024-01-07 17:25:11
游戏开发小结——创建wave系统
目标:学习如何实现Wave系统。
目前,我们的敌人每隔几秒就会无限期地随机生成。现在我们想将其更新为Wave系统,这意味着每一波都会产生一定数量的敌人,每一波都会变得越来越难。
击败一波后,下一波将包含更多敌人、更快的敌人,而且生成速度也更快。
由于我们要在游戏中实现Wave系统,因此最好有一条消息告诉玩家下一波何时开始。
[SerializeField] private TextMeshProUGUI _waveSpawnText;
[SerializeField] private TextMeshProUGUI _waveNumberText;
有了文本的新变量,我们只需在检查器上调整它们即可。
在检查器中分配我们的变量。
这样我们的 UIManager 就准备好进行编码了。让我们从这里开始吧。
public void UpdateWaveText(int wave)
{
_waveNumberText.text = "Wave: " + wave.ToString();
}
这个很简单。当我们有一个新的wave时,我们只需调用这个方法来更新显示。
public IEnumerator NextWaveSpawnRoutine(int wave)
{
_waveSpawnText.gameObject.SetActive(true);
for (int i = 5; i >= 0; i--)
{
if(i > 0)
{
_waveSpawnText.text = "WAVE " + wave + " STARTS IN " + i + "!";
yield return _waveDelay;
}
else
{
_waveSpawnText.text = "WAVE " + wave + " STARTS NOW !";
yield return _nowDelay;
}
}
_waveSpawnText.gameObject.SetActive(false);
}
现在我们的协程(Coroutine)。这就是我们在下一波开始时向玩家展示的方式。我们有一个从 5 倒数到零的循环。每秒它都会用当前波形和第二个波形更新显示。
当它达到零时,它只是说波正在开始,短暂的延迟后,我们关闭文本。
我们的
NextWaveSpawnRoutine 正在运行。
现在我们的 SpawnManager。这将包含更多变量和变化。
private int _currentWave = 1;
private int _enemiesPerWave = 5;
private float _spawnInterval = 5.0f;
private float _enemySpeedMultiplier = 1f;
private float _spawnIntervalDecreasePercentage = 10f;
private List<GameObject> _activeEnemies = new List<GameObject>();
所以我们的 SpawnManager 有 6 个新变量。让我们把它们分解一下:
- _currentWave:保存游戏的当前波次。
- _enemiesPerWave:保存应该生成的敌人数量。
- _spawnInterval:保存敌人生成的时间间隔。
- _enemySpeedMultipler:保存敌人速度的乘数,使我们的敌人更快。
- _spawnIntervalDecreasePercentage:保存每一波相对于前一波的速度快多少。
- _activeEnemies:保存游戏中所有活着的敌人的列表。这用于我们检查生成的所有敌人是否都已死亡,并且我们可以开始下一波。
private IEnumerator EnemySpawnRoutine()
{
yield return UIManager.Instance.NextWaveSpawnRoutine(_currentWave);
while (!_isPlayerAlive)
{
for (int i = 0; i < _enemiesPerWave; i++)
{
SpawnEnemy();
yield return new WaitForSeconds(_spawnInterval);
}
while (_activeEnemies.Count > 0)
{
yield return null;
}
_currentWave++;
_enemiesPerWave += 2;
_spawnInterval *= 1.0f - (_spawnIntervalDecreasePercentage / 100.0f);
_enemySpeedMultiplier += 0.05f;
UIManager.Instance.UpdateWaveText(_currentWave);
yield return UIManager.Instance.NextWaveSpawnRoutine(_currentWave);
}
}
现在我们的协程。首先,我们使用 UIManager 中的协程的 Yield Return,这是我们的 NextWaveSpawnRoutine。我们将当前的波作为参数传递。这告诉 Unity 等待协程完成,然后再执行其余代码。
在我们的循环中,只要我们的玩家活着,它就会运行。我们首先执行一个循环,在 EnemiesPerWave 变量中生成所有敌人。
在我们的循环中,我们Yield Return返回 SpawnInterval,它从 5 秒开始,但随着游戏的进行而变得越来越快。
所有敌人生成后,我们检查是否还有活着的敌人。这是在我们的 While 循环内完成的。当有任何活着的敌人时,我们只是 Yield Return null。
当所有敌人都死后,我们就离开循环。然后我们继续增加用于我们的波浪系统的所有变量。确保我们的波数增加,就会产生更多的敌人,产生的间隔会更短,而我们的敌人会更快。
然后我们更新 UIManager 以匹配正确的 Wave,并yield return返回下一个 Wave 的协程。
现在我们的敌人。由于我们要提高敌人的移动速度,因此当我们的敌人生成时将调用此方法。
private void SpawnEnemy()
{
float randomPositionX = Random.Range(_minXPosition, _maxXPosition);
_enemySpawnPosition.Set(randomPositionX, _spawnPositionY, 0f);
var enemy = Instantiate(_enemyPrefab, _enemySpawnPosition, Quaternion.identity, _enemyContainer.transform);
_activeEnemies.Add(enemy);
var enemyBehavior = enemy.GetComponent<EnemyBehavior>();
if (enemyBehavior != null)
enemyBehavior.IncreaseSpeed(_enemySpeedMultiplier);
}
仍然在我们的 SpawnManager 中,当实例化我们的敌人时,我们现在正在抓住敌人的手柄。完成此操作后,我们可以将他添加到我们的列表中,并获取他的 EnemyBehavior 脚本的句柄。在空检查之后,我们只需确保调用我们接下来要创建的方法,这会增加敌人的移动速度。
最后对于我们的 SpawnManager,在敌人被摧毁后,我们需要将他从我们的列表中删除。我们将创建一个方法,敌人可以在其中提供其游戏对象,这样我们就可以将他从列表中删除。
public void DestroyEnemy(GameObject enemy)
{
_activeEnemies.Remove(enemy);
}
现在我们转向 EnemyBehavior 脚本。我们需要我们的方法来提高移动速度,该方法在敌人实例化后调用。
public void IncreaseSpeed(float multiplier)
{
_enemySpeed *= multiplier;
}
这使我们能够传递一个乘数,这将提高敌人的移动速度。每波都会将我们的移动速度提高 5%,但如果需要的话可以更改。
public void TakeDamage()
{
_animator.SetTrigger(_onEnemyDeathHash);
_enemySpeed = 0f;
_audioSource.Play();
Destroy(gameObject, 2.5f);
SpawnManager.Instance.DestroyEnemy(gameObject);
Destroy(this);
}
现在,在我们的 TakeDamage 方法中,我们只需确保从 SpawnManager 调用 DestroyEnemy,传递我们的游戏对象作为引用,确保从我们的活动敌人中删除正在被摧毁的敌人。
当我们的最后一个敌人被消灭后,我们就进入下一波。
现在我们的 Wave 系统已经完全正常工作了。正如我们所看到的,消灭最后一个敌人后,我们只需进入 NextWaveSpawnRoutine,它们就会继续产生更多敌人,每一波敌人都会变得更强!
文章来源:https://blog.csdn.net/qq_37270421/article/details/135351583
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!