Почему моя функция запускается дважды в OnTriggerStay? - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть простая игра в 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;
        }
    }
}

1 Ответ

0 голосов
/ 25 февраля 2020

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

Может быть, оба ваших события (Enter & Stay) будут запущены в течение этого кадра?

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

OnTriggerStay вызывается почти всеми кадрами для каждого другого коллайдера, который касается триггера. Эта функция включена на физическом таймере, поэтому она не обязательно будет запускать каждый кадр.

...