Unity - 太空射手2D - 当游戏对象被破坏时,忽略OnTriggerEnter(触发输入)。

问题描述 投票:-1回答:2

我是Unity新手,用2D制作了一个小小的太空射击游戏。

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

当玩家收集到一个能量时,他可以在同一时间发射2个螺栓。如果这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;
    }
}
c# unity3d
2个回答
1
投票

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

它可能是这样的

bool isDestroyed = false;

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

0
投票

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

void OnDestroy(){
    player.IncrementScore();
}
© www.soinside.com 2019 - 2024. All rights reserved.