首页 > 解决方案 > 为什么我的函数在 OnTriggerStay 中运行了两次?

问题描述

我在Unity中有一个简单的游戏。

这种情况就像如果我杀死一个敌人,它会掉落一个可拾取的生命值。在OnTriggerEnter中,我处理玩家与健康的碰撞,如果玩家错过健康,它会治愈一定量。(确切地说是 70)

当玩家在最大生命值时站在生命值上时,它什么也不做。但是如果玩家站在生命值上受到伤害,生命值也应该被拾起,这就是OnTriggerStay的用武之地。

在那里我不断检查玩家是否需要倾斜,如果需要,进行治疗并摧毁治疗对象。我的问题是它运行了两次。它会为玩家治疗两次。无论我做什么,我在OnTriggerStay中调用的函数都会运行两次。这是为什么?有人知道解决方案吗?

这是我的 Player.cs 文件和 Heal.cs 文件的一部分:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
  //HP and MANA system
    [SerializeField]
    private int playerHealth;
    [SerializeField]
    private int playerMaxHealth = 100;
    [SerializeField]
    private Transform Healthbar;

    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Enemy")
        {
            timer += Time.deltaTime;
            if (timer > attackSpeed)
            {
                Enemy enemy = other.GetComponent<Enemy>();
                if (enemy != null)
                {
                    enemy.DamageEnemy(playerDamage);
                }
                timer = 0.0f;
            }
        }
        if (other.tag == "PatrollingEnemy")
        {
            timer += Time.deltaTime;
            if (timer > attackSpeed)
            {
                PatrollingEnemy enemy = other.GetComponent<PatrollingEnemy>();
                if (enemy != null)
                {
                    enemy.DamageEnemy(playerDamage);
                }
                timer = 0.0f;
            }
        }
        if (other.tag == "Heal")
        {
            heal(other, false);

        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Heal")
        {
            heal(other, false);
        }
        else if (other.tag == "HealthPotion")
        {
            heal(other, true);
        }
    }
    private void heal(Collider other, bool isPotion)
    {

        dynamic heal;
        if (isPotion)
        {
            heal = other.GetComponent<HealthPotion>();
        }
        else
        {
            heal = other.GetComponent<Heal>();
        }
        if (playerHealth < playerMaxHealth && heal != null)
        {
            addHealthToPlayer(heal.HealAmount);
            Destroy(other.gameObject);
        }
    }

    private void addHealthToPlayer(int amount)
    {

        playerHealth += amount;
        if (playerHealth > playerMaxHealth)
        {
            playerHealth = playerMaxHealth;
        }
        rescaleHealthBar();
    }

    private void rescaleHealthBar()
    {
        Healthbar.transform.localScale = new Vector3((float)playerHealth / (float)playerMaxHealth, 1.0f, 1.0f);
    } 
}


public class Heal : MonoBehaviour
{
    float timer = 0.0f;
    float destroyTimer = 0.0f;
    float timeWhenDestroy = 15f;
    Vector3 rotation = new Vector3(0, 45, 0);

    private int healAmount = 70;
    public int HealAmount
    {
        get
        {
            return healAmount;
        }
    }

    void Update()
    {
        timer += Time.deltaTime;
        destroyTimer += Time.deltaTime;
        if (destroyTimer > timeWhenDestroy)
        {
            Destroy(this.gameObject);
        }
        transform.Rotate(rotation * Time.deltaTime);
        if (timer < 1.0f)
        {
            transform.Translate(Vector3.up * Time.deltaTime);
        }
        if (timer > 1.0f)
        {
            transform.Translate(-Vector3.up * Time.deltaTime);
        }
        if (timer > 2.0f)
        {
            timer = 0.0f;
        }
    }
}

标签: c#unity3dcollision

解决方案


https://docs.unity3d.com/ScriptReference/Object.Destroy.html

也许您的两个事件(进入和停留)都在该帧期间被触发?

https://docs.unity3d.com/ScriptReference/Collider.OnTriggerStay.html

OnTriggerStay 几乎在所有触碰触发器的 Collider 的所有帧中都被调用。该功能位于物理计时器上,因此不一定会运行每一帧。


推荐阅读