Unity-Space Shooter 2D-当游戏对象被摧毁时忽略OnTriggerEnter



我是Unity的新手,在2D中创建了一个小型太空射击游戏。

当玩家用枪栓射击敌人时,敌人的物体被摧毁,玩家获得1分。

当玩家获得能量时,他可以同时发射2个螺栓。如果这两颗闪电击中敌人,玩家将不幸获得2分,而不是1分。敌人的附加脚本"DestroyByContact"中的方法OnTriggerEnter被调用两次。

如果游戏对象被破坏,我如何忽略OnTriggerEnter?也许有人能帮我。

我在下面添加了OnTriggerEnter方法的代码。

private void OnTriggerEnter(Collider other)
{
switch (gameObject.tag)
{
case "Player":
{
if (other.CompareTag("Asteroid"))
{
if (playerController.HasShield())
{
Destroy(other.gameObject); // Asteroid
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
playerController.RemoveShield();
}
else
{
Destroy(other.gameObject); // Asteroid
Destroy(gameObject); // Player
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver();
}
}
if (other.CompareTag("Enemy"))
{
if (playerController.HasShield())
{
Destroy(other.gameObject); // Enemy
Instantiate(enemyExplosion, other.transform.position, other.transform.rotation);
playerController.RemoveShield();
}
else
{
Destroy(other.gameObject); // Enemy
Destroy(gameObject); // Player
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver();
}
}
if (other.CompareTag("BoltEnemy"))
{
if (playerController.HasShield())
{
Destroy(other.gameObject); // BoltEnemy
playerController.RemoveShield();
}
else
{
Destroy(other.gameObject); // BoltEnemy
Destroy(gameObject); // Player
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver();
}
}
if (other.CompareTag("Boss"))
{
// if player ship hits the boss, player gets destroyed, no matter if he has a shield left or not
if (playerController.HasShield())
{
playerController.RemoveShield();
}
Destroy(gameObject); // Player
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.GameOver();
}
if (other.CompareTag("PowerUpBolt"))
{
Destroy(other.gameObject); // PowerUpBolt
audioPowerUp.Play();
playerController.IncreaseShotSpawns();
}
if (other.CompareTag("PowerUpHealth"))
{
Destroy(other.gameObject); // PowerUpHealth
audioPowerUp.Play();
if (!playerController.HasShield())
{
playerController.AddShield();
}
}
}
break;
case "Asteroid":
{
if (other.CompareTag("BoltPlayer"))
{
Destroy(other.gameObject); // BoltPlayer
Destroy(gameObject); // Asteroid
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
gameController.AddScore(scoreValueAsteroid);
}
}
break;
case "Enemy":
{
if (other.CompareTag("BoltPlayer"))
{
Destroy(other.gameObject); // BoltPlayer
Destroy(gameObject); // Enemy
Instantiate(enemyExplosion, other.transform.position, other.transform.rotation);
gameController.AddScore(scoreValueEnemy);
gameController.SpawnPowerUp(other.transform);
}
}
break;
case "Boss":
{
if (other.CompareTag("BoltPlayer"))
{
Destroy(other.gameObject); // BoltPlayer
bossController.GotHit();
if (bossController.IsDefeated())
{
Destroy(gameObject); // Boss
Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
gameController.Success();
}
}
}
break;
}
}

调用Destroy之后,Unity标记给定对象进行销毁,但直到下一帧才销毁。为了避免两次调用你的方法,只需将bool变量添加到你的敌人类中,并在OnTriggerEnter中进行检查

它可能看起来像这个

bool isDestroyed = false;
void OnTriggerEnter(Collider other)
{
if (isDestroyed) return;
else
{
isDestroyed = true;
Destoy(gameObject);
// whatever else should happen
}
}

正如其他答案中所提到的,Destroy()将在当前帧的末尾销毁一个对象,因此,当脚本在同一帧中被调用两次时,您将获得两分
幸运的是,Unity有一个功能可以避免这种情况,如果你在OnDestroy()中增加分数,那么它保证只发生一次。

void OnDestroy(){
player.IncrementScore();
}

最新更新