在Unity游戏开发过程中,经常会遇到各种问题和挑战。今天,将讨论如何在游戏中新增敌人,并解决一个射击时敌人未被击中的bug。
已经准备好了一切,现在可以开始使用它们了!在完成了生成系统并玩了一会儿游戏后,发现了一个小问题。有时,当射击时,敌人并没有被击中。这在尝试将敌人的生命值切换为1时变得很明显。今天的目标是:
开始生成所有的3个敌人。修复射击bug。
让立即开始吧!
在Unity的层级结构中,查看GameManager > SpawnManager,并找到SpawnManager脚本。将Waves size设置为3。想要生成:
完成之后,将能够在游戏中与所有新敌人战斗!
现在已经生成了敌人并开始玩游戏,可能会遇到一个非常奇怪的问题。当射击敌人时,有时他们并没有被击中。并不是在谈论远距离,说的是非常近的距离。发生了什么?
经过一番挖掘,发现了问题:射线仍然击中了死去敌人的网格碰撞体。正如在第20天讨论的那样,附加到敌人的网格碰撞体并不遵循敌人的形状。它们只是仍然在那里,就像上面的图片所示。
这里发生的情况是,尽管击败了敌人,他们的网格碰撞体仍然阻挡了射击,使无法击中其他现有的敌人。但这没关系,可以修复这个问题。当敌人死亡时,必须禁用附加在敌人上的所有碰撞体。
现在,让想一想,在哪里知道敌人已经死亡?在EnemyAttack脚本中!在EnemyAttack中,有一个名为Death()的函数,负责处理敌人死亡时的所有事情。让使用它:
using UnityEngine;
public class EnemyHealth : MonoBehaviour {
public float Health = 100;
public AudioClip[] HitSfxClips;
public float HitSoundDelay = 0.5f;
private SpawnManager _spawnManager;
private Animator _animator;
private AudioSource _audioSource;
private float _hitTime;
void Start() {
_spawnManager = GameObject.FindGameObjectWithTag("SpawnManager").GetComponent();
_animator = GetComponent();
_hitTime = 0f;
SetupSound();
}
void Update() {
_hitTime += Time.deltaTime;
}
public void TakeDamage(float damage) {
if (Health <= 0) {
return;
}
Health -= damage;
if (_hitTime > HitSoundDelay) {
PlayRandomHit();
_hitTime = 0;
}
if (Health <= 0) {
Death();
}
}
private void SetupSound() {
_audioSource = gameObject.AddComponent();
_audioSource.volume = 0.2f;
}
private void PlayRandomHit() {
int index = Random.Range(0, HitSfxClips.Length);
_audioSource.clip = HitSfxClips[index];
_audioSource.Play();
}
private void Death() {
_animator.SetTrigger("Death");
_spawnManager.EnemyDefeated();
foreach (Collider collider in GetComponentsInChildren()) {
collider.enabled = false;
}
}
}
所做的唯一重大更改是在Death()中,搜索敌人的所有子游戏对象,寻找任何碰撞体组件。如果找到了碰撞体,只需禁用它。
值得注意的是,在寻找任何类型的Collider。更习惯于找到确切类型的组件,例如GetComponent