"Об'єкт, який ви бажаєте інсталювати, є нульовим", але він працює, чи можу я проігнорувати помилку?


18

Такого ніколи не траплялося зі мною, тому я трохи розгублений.

GameObject someObject = Instantiate (Resources.Load ("Prefabs/Items/" + someName)) as GameObject;

Це призводить до помилки, але об'єкт фактично створений і все працює за призначенням. Помилка не зупиняє програму незалежно від того, скільки разів я це відтворюю.

Чи можу я проігнорувати цю помилку чи є якась проблема, яку я не бачу?


32
ніколи не слід ігнорувати помилки. Вони завжди є чомусь;)
Габріеле Вієрті

5
Хочеться відмовитись від ідеї ніколи не ігнорувати помилки лише тому, що "це працює". За визначенням, якщо є помилка, вона не працює. Звичайно, це може здатися робити все, що ви хочете, але це просто означає, що ви ще не знайшли зламаного шматочка.
Фонд позову Моніки

Відповіді:


46

Якщо об'єкт встановлений у встановленому порядку правильно, незважаючи на те, що Intantiate()рядок викидає виняток, помилка надходить з іншого екземпляра сценарію - у вас може бути випадково друга копія у вашій сцені.

Один екземпляр налаштовано правильно та виконує Instantiate()як очікується, без помилок, тому об’єкт створюється за бажанням.

Інший екземпляр налаштований неправильно і видає помилку. Але якщо ви просто дивитесь на правильно налаштований екземпляр, ця помилка, здається, з’явиться нізвідки і не матиме видимих ​​наслідків.

Ви можете роздрукувати шлях до об'єкта на пуску - або під час нульової перевірки перед рядком-порушником - щоб допомогти відстежити небажані дублікати сцени.

Ви абсолютно не повинні ігнорувати цю помилку.

У кращому випадку це спалювання обчислювальних циклів без потреби. У гіршому випадку, це знак того, що у вашій грі робиться щось, чого ви не повністю розумієте, і це може бути корінням набагато більших проблем.


12
+1, помилки - це не те саме, що попередження, якщо є помилка, ти ніколи не знаєш, коли вона перейде до всієї гри, що виходить з ладу.
TomTsagk

13
Не завжди безпечно ігнорувати попередження. Навіть якщо це не помилка, вона все одно може призвести до ситуації, коли гра виходить з ладу.
Шон Бертон

2
Я погоджуюся з @SeanBurton, ігнорування попереджень не є безпечною практикою. Вам слід ігнорувати попередження, якщо, і лише тоді, ви розумієте, що це викликає, і вам зручно, що це не спричиняє проблеми у вашому коді. Вже тоді запитайте себе, чи не могли б ви зробити це краще.
Джек Едлі

3
Кожен проект, над яким я працював із великою командою, в якийсь момент настільки перевантажився "необережними" попередженнями, що почав маскувати справжні проблеми. Тож я б напевно виступав за те, щоб серйозно ставитись до попереджень, і якщо це неминуче, вимкніть його для відповідного рядка разом із коментарем, що чітко визначає, чому можна безпечно пропустити подання попередження.
DMGregory

1
Я на 100% з @DMGregory, я працював лише над дуже маленькими командами, але пару разів попередження почали складатись, було жахливо знаходити "справжні" проблеми, інакше ти їх весь час будеш сумувати. Мій MO полягає в тому, щоб журнал був чистим, за винятком тестування, навіть якщо мені доведеться відключити попередження щодо коду плагінів (будь ласка, не робіть плагіни з попередженнями ВСЕ), це набагато краще в довгостроковому періоді IMO. Редагувати: щоб бути зрозумілим, ніколи не вимикайте попередження, якщо ви не впевнені на 100%, що немає іншого шляху (що трапляється 0,001% часу), завжди фактично їх виправляйте.
Трисібо

21

Відповідь

Дозвольте розпочати, прямо відповівши на ваше запитання:

це працює, чи можу я ігнорувати помилку?

Ти міг би . Не слід , бо це означає, що щось не так. Ви звикли б до цієї помилки, але вона може "приховати" або викликати іншу помилку.

На даний момент у вас є повідомлення про помилку, і воно все ще працює правильно. І навпаки, це не працює і не має (точніше, не визнає) зворотного зв'язку чому, набагато гірше!

Поради

Щоб дізнатися, звідки це походить, розділіть всю цю річ на кілька рядків.

string resourceLocation = "Prefabs/Items/" + someName;
Object prefab = Resources.Load(resourceLocation);
Object instance = Instantiate(prefab);
GameObject someObject = instance as GameObject;

Помилка повідомляє лише вам, у якому рядку це сталося. Якщо в цьому коді сталася помилка, номер рядка розповість більше про те, яка частина тут пішла не так. Також я б радив використовувати загальну версію Resources.Load, що насправді дасть нам на крок менше турбуватися:

string resourceLocation = "Prefabs/Items/" + someName;
GameObject prefab = Resources.Load<GameObject>(resourceLocation);
GameObject someObject = Instantiate(prefab);

З’ясування, чому

  • Тепер трохи досвіду Єдності говорить нам, що "Об'єкт, на який Ви хочете вступити - нульовий", викликаний Instantiate().
  • Таким чином, це означає , що prefabє null.
  • Так що це означає Resources.Loadприбутки null.
  • ДокументаціяResources.Load говорить « повернення активу в pathразі його можна знайти в іншому випадку повертає NULL. »
  • Отже, це означає, що він не знаходить заданий шлях (рядок, який я зателефонував resourceLocation)

У цьому шляху щось не так, тож очевидним першим кроком було б побачити, чим він насправді закінчується, з Debug.Log. Оскільки "все працює за призначенням", його ймовірність того, що відбувається певне дублювання там, де працює одна версія, а інша - це помилка.

У такому випадку корисно використовувати версію 2-х параметрів Debug.Log Debug.Log(resourceLocation, gameObject);. Тепер, якщо ви натиснете на повідомлення журналу в редакторі Unity, він вибере, GameObjectзвідки воно прийшло.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.