@WalloutDay

Unity: NullReferenceException: Object reference not set to an instance of an object в чём ошибка?

Выбивает ошибку. ebce34484e1a4e02b527c17a68fdd126.png Уже даже и не знаю что делать. Скрипты если что висят на разных объектах. Первый на зомби, второй на игроке. Надо запустить с скрипта зомби функцию TakeDamage в скрипте игрока. Вот где ошибка. 33b2338079804bbaa7fa88ccc7e25028.png

А вот и два скрипта.
1-Скрипт зомби:
using UnityEngine;
using System.Collections;

public class ZombieAttack : MonoBehaviour
{

    public int zombieCol = 0;
    float timer;
    public float timeBetweenAttacks = 0.5f;
    public int attackDamage;
    HealthScript enemyHealth;
    HealthCharacter playerHealth;

    void Awake()
    {

        playerHealth = GetComponent<HealthCharacter>();
        enemyHealth = GetComponent<HealthScript>();

    }
    
    void OnTriggerEnter2D(Collider2D col)
    {

        if (col.gameObject.name == "Character")
        {
            zombieCol = 1;
        }

    }

    void OnTriggerExit2D(Collider2D col)
    {

        if (col.gameObject.name == "Character")
        {
            zombieCol = 0;
        }

    }

    void Update()
    {

        if (zombieCol == 1)
        {

            ZombieController move = GetComponent<ZombieController>();
            move.playerSpeedForOtherScript = 0;

            timer += Time.deltaTime;

            if (timer > timeBetweenAttacks && enemyHealth.HP > 0)
            {

                Attack();

            }
        }
    }

    void Attack()
    {

        timer = 0f;
        
        if (playerHealth.HP > 0)
        {

            playerHealth.TakeDamage(attackDamage);

        }

    }

}


2-Скрипт персонажа:
using UnityEngine;
using System.Collections;

public class HealthCharacter : MonoBehaviour
{

    public float HP;
    public bool isEnemy = true;
    public UISprite healthSprite;
    public float attackZombieRadi;
    public float timeBetweenAttack;

    float timer;
    public bool zombieAttack;

    void Awake()
    {

       healthSprite.fillAmount = 1;

    }

    void Update()
    {

        timer += Time.deltaTime;

        healthSprite.fillAmount = HP / 100;
        
        if (HP <= 0)
        {

            healthSprite.fillAmount = 0f;
            Destroy(gameObject);

        }
        
    }

    public void TakeDamage (int amount)
    {

        HP -= amount;

    }
}
  • Вопрос задан
  • 1032 просмотра
Решения вопроса 1
lexxpavlov
@lexxpavlov
Программист, преподаватель
Я думаю, проблема как раз в том, что у вас разные компоненты у разных объектов - у зомби пытаетесь получить доступ к объекту скрипта жизней, но этот скрипт у персонажа, а не у зомби, поэтому playerHealth = GetComponent(); даст null.

Вы неправильно пытаетесь связываться с разными объектами. В одном объекте не нужно иметь ссылку на объект другого персонажа. А как же тогда уменьшить жизни? Через событие - у вас есть OnTriggerEnter2D - вот в нём есть ссылка на тот объект, с которым только что столкнулся, вот в нём и нужно выбивать жизни:
void OnTriggerEnter2D(Collider2D col)
{
    if (col.gameObject.name == "Character")
    {
        var pers = col.gameObject.GetComponent<HealthCharacter>();
        if (pers != null)
        {
            pers.TakeDamage(attackDamage);
        }
    }
}

И не надо проверять объект по его имени (я имею в виду код if (col.gameObject.name == "Character") ), в Юнити есть прекрасная штука - теги. Создайте тег Enemy и тег Hero (или как у вас там персонаж называется), и вот по ним проверяйте - с ним столкнулся, или нет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы