Потерянная ссылка после выполнения метода - PullRequest
0 голосов
/ 03 ноября 2019

Я следовал этому видео о том, как автоматически создавать полосы здоровья для юнитов. Это мой класс HealthBar.

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

    public class HealthBar : MonoBehaviour
    {
        #region SerializeFields

        [SerializeField] private Image foregroundImage;
        [SerializeField] private float updateSpeedInSec = 0.5f;
        [SerializeField] private float positionOffset = 1f;

        #endregion

        #region NonSerializeFields

        private Health health;

        #endregion

        public void SetHealth(Health healthToSet)
        {
            health = healthToSet;
            healthToSet.OnHealthPctChanged += HandleHealthChanged;
        }

        private void HandleHealthChanged(float pct)
        {
            StartCoroutine(ChangeToPct(pct));
        }

        private IEnumerator ChangeToPct(float pct)
        {
            float preChangedPct = foregroundImage.fillAmount;
            float elapsedTime = 0f;

            while (elapsedTime < updateSpeedInSec)
            {
                elapsedTime += Time.deltaTime;
                foregroundImage.fillAmount = Mathf.Lerp(preChangedPct, pct, elapsedTime / updateSpeedInSec);
                yield return null;
            }

            foregroundImage.fillAmount = pct;
        }

        private void LateUpdate()
        {
            var worldToScreenPoint = Camera.main
                .WorldToScreenPoint(health.transform.position + (Vector3) Vector2.up * positionOffset);
            transform.position = worldToScreenPoint;
        }

        private void OnDestroy()
        {
            health.OnHealthPctChanged -= HandleHealthChanged;
        }
    }

Итак, это мой класс HealthBarController, в котором вызывается метод SetHealth, помещенный на холст.

using System.Collections.Generic;
using UnityEngine;

public class HealthBarController : MonoBehaviour
{
    #region SerializeFields

    [SerializeField] private HealthBar healthBar;

    #endregion

    #region NonSerializeFields

    private Dictionary<Health, HealthBar> healthBars = new Dictionary<Health, HealthBar>();

    #endregion

    private void Awake()
    {
        Health.OnHealthAdded += AddHealthBar;
        Health.OnHealthRemoved += RemoveHealthBar;
    }

    private void AddHealthBar(Health health)
    {
        if (healthBars.ContainsKey(health)) return;

        var newHealthBar = Instantiate(healthBar, transform);
        healthBars.Add(health, newHealthBar);
        healthBar.SetHealth(health);
    }

    private void RemoveHealthBar(Health health)
    {
        if (!healthBars.ContainsKey(health)) return;

        Destroy(healthBars[health].gameObject);
        healthBars.Remove(health);
    }
}

Иэто мой класс здоровья персонажа игрока.

using System;
using UnityEngine;

public class Health : MonoBehaviour, IDamageable
{
    #region SerializeFields

    [SerializeField] protected int maxHealth = 100;

    public static event Action<Health> OnHealthAdded = delegate {  };
    public static event Action<Health> OnHealthRemoved = delegate {  };
    public event Action<float> OnHealthPctChanged = delegate {  };

    #endregion

    #region NonSerializeFields

    protected int currentHealth;

    #endregion

    private void OnEnable()
    {
        currentHealth = maxHealth;
        OnHealthAdded(this);
    }

    public void TakeDamage(int damage)
    {
        currentHealth -= damage;
        float currentHealthPct = (float) currentHealth / maxHealth;
        OnHealthPctChanged(currentHealthPct);

        if (currentHealth <= 0)
        {
            Die();
        }
    }

    protected void Die()
    {
        OnHealthRemoved(this);
        Destroy(gameObject);
    }
}

Проблема, с которой я сталкиваюсь, заключается в методе LateUpdate, поле health пусто, хотя в методе SetHealth,он был установлен правильно.

1 Ответ

0 голосов
/ 04 ноября 2019

В методе AddHealthBar вашего сценария HealthBarController.cs вы назначаете класс Health вашего персонажа префабу healthBar, а не только что созданному экземпляру Health newHealthBar. .

Просто замените healthBar.SetHealth(health); на newHealthBar.SetHealth(health); (строка 30).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...