Nullreferenceexception unity как исправить
Перейти к содержимому

Nullreferenceexception unity как исправить

  • автор:

What is a Null Reference Exception?

A NullReferenceException happens when you try to access a reference variable that isn’t referencing any object. If a reference variable isn’t referencing an object, then it’ll be treated as null . The run-time will tell you that you are trying to access an object, when the variable is null by issuing a NullReferenceException .

Reference variables in c# and JavaScript are similar in concept to pointers in C and C++. Reference types default to null to indicate that they are not referencing any object. Hence, if you try and access the object that is being referenced and there isn’t one, you will get a NullReferenceException .

When you get a NullReferenceException in your code it means that you have forgotten to set a variable before using it. The error message will look something like:

NullReferenceException: Object reference not set to an instance of an object at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10 //c# example using UnityEngine; using System.Collections; public class Example : MonoBehaviour < // Use this for initialization void Start () < GameObject go = GameObject.Find("wibble"); Debug.Log(go.name); >> 

Null Checks

Although it can be frustrating when this happens it just means the script needs to be more careful. The solution in this simple example is to change the code like this:

using UnityEngine; using System.Collections; public class Example : MonoBehaviour < void Start () < GameObject go = GameObject.Find("wibble"); if (go) < Debug.Log(go.name); >else < Debug.Log("No game object called wibble found"); >> > 

Try/Catch Blocks

Another cause for NullReferenceException is to use a variable that should be initialised in the Inspector. If you forget to do this, then the variable will be null . A different way to deal with NullReferenceException is to use try/catch block. For example, this code:

using UnityEngine; using System; using System.Collections; public class Example2 : MonoBehaviour < public Light myLight; // set in the inspector void Start () < try < myLight.color = Color.yellow; >catch (NullReferenceException ex) < Debug.Log("myLight was not set in the inspector"); >> > 

Сводка

  • NullReferenceException happens when your script code tries to use a variable which isn’t set (referencing) and object.
  • The error message that appears tells you a great deal about where in the code the problem happens.
  • NullReferenceException can be avoided by writing code that checks for null before accessing an object, or uses try/catch blocks. This error message says that a NullReferenceException happened on line 10 of the script file Example.cs . Also, the message says that the exception happened inside the Start() function. This makes the Null Reference Exception easy to find and fix. In this example, the code is: The code simply looks for a game object called “wibble”. In this example there is no game object with that name, so the Find() function returns null . On the next line (line 9) we use the go variable and try and print out the name of the game object it references. Because we are accessing a game object that doesn’t exist the run-time gives us a NullReferenceException Now, before we try and do anything with the go variable, we check to see that it is not null . If it it null , then we display a message. In this code example, the variable called myLight is a Light which should be set in the Inspector window. If this variable is not set, then it will default to null . Attempting to change the color of the light in the try block causes a NullReferenceException which is picked up by the catch block. The catch block displays a message which might be more helpful to artists and game designers, and reminds them to set the light in the inspector.

Unity ошибка NullReferenceException, как исправить?

Заранее благодарю
public void BuyBttn(int index) //Метод при нажатии на кнопку покупки товара (индекс товара)
int cost = shopItems[index].cost * shopItems[shopItems[index].itemIndex].bonusCounter; //Рассчитываем цену в зависимости от кол-ва рабочих (к примеру)
if (shopItems[index].itsBonus && score >= cost) //Если товар нажатой кнопки — это бонус, и денег >= цены (е)
if (cost > 0) // Если цена больше чем 0, то:
score -= cost; // Вычитаем цену из денег
StartCoroutine(BonusTimer(shopItems[index].timeOfBonus, index)); //Запускаем бонусный таймер
>
else print(«Нечего улучшать то!»); // Иначе выводим в консоль текст.
>
else if (score >= shopItems[index].cost) // Иначе, если товар нажатой кнопки — это не бонус, и денег >= цена
if (shopItems[index].itsItemPerSec) shopItems[index].bonusCounter++; // Если нанимаем рабочего (к примеру), то прибавляем кол-во рабочих
else scoreIncrease += shopItems[index].bonusIncrease; // Иначе бонусу при клике добавляем бонус товара
score -= shopItems[index].cost; // Вычитаем цену из денег
if (shopItems[index].needCostMultiplier) shopItems[index].cost *= shopItems[index].costMultiplier; // Если товару нужно умножить цену, то умножаем на множитель
shopItems[index].levelOfItem++; // Поднимаем уровень предмета на 1
>
else print(«Не хватает денег!»); // Иначе если 2 проверки равны false, то выводим в консоль текст.
updateCosts(); //Обновить текст с ценами
>
private void updateCosts() // Метод для обновления текста с ценами
for (int i = 0; i < shopItems.Count; i++) // Цикл выполняется, пока переменная i < кол-ва товаров
if (shopItems[i].itsBonus) // Если товар является бонусом, то:
int cost = shopItems[i].cost * shopItems[shopItems[i].itemIndex].bonusCounter; // Рассчитываем цену в зависимости от кол-ва рабочих (к примеру)
shopItemsText[i].text = shopItems[i].name + «\n» + cost + «$»; // Обновляем текст кнопки с рассчитанной ценой
>
else shopItemsText[i].text = shopItems[i].name + «\n» + shopItems[i].cost + «$»; // Иначе если товар не является бонусом, то обновляем текст кнопки с обычной ценой
>
>

Голосование за лучший ответ

Проследи, что у тебя все массивы и переменные заполнены объектами.
SomeObject obj = null;
obj.name = «Name»; // NullReferenceException

Ругается что ты пытаешься использовать объект, который не существует. Либо данные в массив вносятся некорректно, или ты где-то их сам обнуляешь/уничтожаешь

Ошибка в Unity3D NullReferenceException: Object reference not set to an instance of an object.Почему?

Делаю простую игру.Когда игрок собирает ящики,обновляется объект text, который показывает к-ство собраных ящиков.Но получаю ошибку NullReferenceException: Object reference not set to an instance of an object и текст не обновляется.
Помогите плиз,половину дня уже потратил и не могу найти ошибку.

public class CounterController : MonoBehaviour < int numberOfBoxes; Text counterView; // Use this for initialization void Start () < ResetCounter (); >public void IncrementCounter() < numberOfBoxes++; counterView.text = numberOfBoxes.ToString(); >public void ResetCounter() < numberOfBoxes=0; counterView.text = numberOfBoxes.ToString(); >>

Клас PickUpBox

public class PickUpBox : MonoBehaviour < CounterController counterController; void Start () < counterController = GameObject.Find ("Manager").GetComponent(); if (counterController == null) < Debug.LogError ("CounterController не найден."); >> void OnTriggerEnter2D (Collider2D other) < if (other.gameObject.name == "Girl") < Destroy (this.gameObject); counterController.IncrementCounter (); >> >
  • Вопрос задан более трёх лет назад
  • 1283 просмотра

1 комментарий

Простой 1 комментарий

Nullreferenceexception unity как исправить

Если мы собираемся использовать переменную или параметр, которые допускают значение null , то есть представляют nullable-тип (не важно значимый или ссылочный), то, чтобы избежать возникновения NullReferenceException, мы можем проверить на null:

void PrintUpper(string? text) < if (text!=null) < Console.WriteLine(text.ToUpper()); >>

В данном случае если параметр text не равен null, то вызываем у строки метод ToUpper() , который переводит символы строки в верхний регистр.

Кроме того, с помощью оператора is мы можем проверить значение объекта:

объект is значение

Если объект слева от оператора is имеет значение справа от оператора. тогда оператор is возвращает true , иначе возвращается false

Например, проверка параметра/переменной на значение null:

void PrintUpper(string? text)

Или, наоборот, с помощью is not можно проверить отсутствие значения:

void PrintUpper(string? text)

Также можно проверить на соответствие типу, значение которого мы собираемся использовать:

void PrintUpper(string? text)

Подобные проверки еще называются null guard или условно говоря «защита от null».

Оператор ??

Оператор ?? называется оператором null-объединения . Он применяется для установки значений по умолчанию для типов, которые допускают значение null:

левый_операнд ?? правый_операнд

Оператор ?? возвращает левый операнд, если этот операнд не равен null . Иначе возвращается правый операнд. При этом левый операнд должен принимать null. Посмотрим на примере:

string? text = null; string name = text ?? "Tom"; // равно Tom, так как text равен null Console.WriteLine(name); // Tom int? personid = id ?? 1; // равно 200, так как id не равен null Console.WriteLine(personid); // 200

Но мы не можем написать следующим образом:

int x = 44; int y = x ?? 100;

Здесь переменная x представляет значимый тип int и не может принимать значение null, поэтому в качестве левого операнда в операции ?? она использоваться не может.

Также можно использовать производный оператора ??=

string? text = null; text ??= "Sam"; // аналогично // text = text ?? "Sam"; Console.WriteLine(text); // Sam int? ??= 1; // аналогично //id = id ?? 1; Console.WriteLine(id); // 100

Оператор условного null

Иногда при работе с объектами, которые принимают значение null, мы можем столкнуться с ошибкой: мы пытаемся обратиться к объекту, а этот объект равен null. Например, пусть у нас есть следующая система классов:

class Person < public Company? Company < get; set; >// место работы > class Company < public string? WebSite < get; set; >// веб-сайт компании >

Объект Person представляет человека. Его свойство Company представляет компанию, где человек работает. Но человек может не работать, поэтому свойство Company имеет тип Company? , то есть может иметь значение null.

Класс Company в свою очередь содержит свойство WebSite, которое представляет веб-сайт компании. Но у компании может и не быть собственного веб-сайта. Поэтому это свойство имеет тип string? , то есть также допускает значение null.

Допустим, нам надо вывести на консоль заглавными буквами веб-сайт компании, где работает человек (если он, конечно, работает и если у компании, где он работает, есть сайт). На первый взгляд мы можем написать следующую конструкцию:

void PrintWebSite(Person? person) < if (person != null) < if(person.Company != null) < if(person.Company.WebSite != null) < Console.WriteLine(person.Company.WebSite.ToUpper()); >> > > class Person < public Company? Company < get; set; >// место работы > class Company < public string? WebSite < get; set; >// веб-сайт компании >

В методе PrintWebSite() принимаем объект Person? и, чтобы избежать исключения NullReferenceException, последовательно проверяем все используемые значения на null, чтобы в конце с помощью метода ToUpper() вывести заглавными буквами название сайта.

Хоть это и рабочий способ, но для простого вывода строки получается многоэтажная конструкция, но на самом деле ее можно сократить:

void PrintWebSite(Person? person) < if (person != null && person.Company != null && person.Company.WebSite != null) < Console.WriteLine(person.Company.WebSite.ToUpper()); >>

Конструкция намного проще, но все равно получается довольно большой. И чтобы ее упростить, в C# есть оператор условного null (Null-Conditional Operator) — оператор ?. :

объект?.компонент

Если объект не равен null , то происходит обращение к компоненту объекта — полю, свойству, методу. Если объект представляет значение null, обращение к компаненту метода не происходит.

Применим данный оператор, изменив предыдущий пример:

void PrintWebSite(Person? person)

Таким образом, если person не равен null, то происходит обращение к его свойству Company. Если свойство Company не равно null, то идет обрашение к свойству WebSite объекта Company. Если свойство WebSite не равно null, то идет обращение к методу ToUpper() .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *