Задать вопрос
@Dmitriy_Kulakov
Начинающий разработчик на C# под Unity

Unity: ошибка «NullReferenceException» при взаимодействии с объектом. В чём может быть причина?

Задача: игра от 1-го лица. Управление персонажем по джойстикам, пишется под смартфон. Персонаж должен подойти к объекту, увидеть кнопки и брать / бросать объект по тапу на кнопки.

Алгоритм:
1) Игрок (Player) подходит к объекту, с которым нужно взаимодействовать - мяч (Ball)
2) Игрок вступает в коллайдер, дочерний мячу – активируются UI-кнопки подбора (grabButton) и броска (throwButton) мяча:
private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.name == "Player")
        {
            grabButton.SetActive(false);
            throwButton.SetActive(false);
        }
    }


3) При нажатии кнопки «Взять» - активируется метод «Grab»:
public void Grab()
    {
        _rb.useGravity = false;
        _rb.isKinematic = true;
        _rb.MovePosition(_arm.position);
        _fpc.take = true;
    }


4) При нажатии кнопки «Бросить» - активируется метод «Throw»:
public void Throw()
    {
        _rb.AddForce(Camera.main.transform.forward * 800);
        _rb.useGravity = true;
        _rb.isKinematic = false;
        _fpc.take = false;
        //_throw.throwAbility = true;
    }


Вопрос: при нажатии на Throw – ошибка:
NullReferenceException: Object reference not set to an instance of an object
ColliderGrab.Throw () (at Assets/ColliderGrab.cs:48)

Пробовал и метод OnClick, и через if (Input.Getkey) – результат тот же. Пожалуйста, подскажите, в чём проблема. Весь скрипт висит на коллайдере-триггере, дочернем к мячу.

P.S.: я начинающий и это мой первый вопрос, сори за возможные недочёты. Заранее спасибо!

Код целиком:

using UnityEngine;

public class ColliderGrab : MonoBehaviour
{
    public GameObject grabButton;
    public GameObject throwButton;

    public Rigidbody _rb;
    private FpcParam _fpc;
    public Transform _arm;

    private void Start()
    {
        _rb = GameObject.Find("Ball").GetComponent<Rigidbody>();
        _fpc = GameObject.Find("Player").GetComponent<FpcParam>();
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.gameObject.name == "Player")
        {
            grabButton.SetActive (true);
            throwButton.SetActive(true);
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.name == "Player")
        {
            grabButton.SetActive(false);
            throwButton.SetActive(false);
        }
    }

    public void Grab()
    {
        _rb.useGravity = false;
        _rb.isKinematic = true;
        _rb.MovePosition(_arm.position);
        _fpc.take = true;
    }

    public void Throw()
    {
        _rb.AddForce(Camera.main.transform.forward * 800);
        _rb.useGravity = true;
        _rb.isKinematic = false;
        _fpc.take = false;
    }

    private void FixedUpdate()
    {
        if (_rb.isKinematic == true)
        {
            _rb.gameObject.transform.position = _arm.position;
        }
    }
}
  • Вопрос задан
  • 96 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
NikFaraday
@NikFaraday
Student full-stack Developer
public Rigidbody _rb;
    private FpcParam _fpc;
    public Transform _arm;

    private void Start()
    {
        _rb = GameObject.Find("Ball").GetComponent<Rigidbody>();
        _fpc = GameObject.Find("Player").GetComponent<FpcParam>();
    }

public void Throw()
    {
        _rb.AddForce(Camera.main.transform.forward * 800);
        _rb.useGravity = true;
        _rb.isKinematic = false;
        _fpc.take = false;
    }


Таки инициализация на 10 строке:
public Transform _arm;


Объявление переменной это когда вы в коде говорите, что есть такая переменная, что бы в будущем к ней обратиться и работать с ней.

Инициализация переменно это когда вы даёте переменное первоначальное значение. Для ссылочных типов (Классы и т.д.) стандартное значение это null. Когда вы вызываете конструктор к классу либо передаёте ему ссылку (Через конструктор) такого же типа, ваша переменная уже считается инициализиваронной

Ссылочные классы так называются, поскольку они не хранят в себе информацию о внутренним состоянии, а ссылаются на фрагмент памяти, где хранится эта информация. Стандартное значение null указывается, что ссылка существует, но она никуда не указывается (Аналогично, когда вы в поисковике переходите по ссылке на страницу, которой не существует).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AshBlade
@AshBlade Куратор тега C#
Просто хочу быть счастливым
Не вижу инициализации _arm
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы