«Объект, который вы хотите создать, равен нулю». Но он работает, могу ли я игнорировать ошибку?

18

Это никогда не случалось со мной, поэтому я немного растерялся.

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

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

Могу ли я игнорировать эту ошибку или есть какая-то проблема, которую я не вижу?

user4676310
источник
32
Вы никогда не должны игнорировать ошибки. У них всегда есть причина;)
Габриэле Виерти
5
Я хочу поддержать идею никогда не игнорировать ошибки только потому, что «это работает». По определению, если есть ошибка, она не работает. Конечно, может показаться, что он делает все, что вы хотите, но это просто означает, что вы еще не нашли сломанный бит.
Фонд Моника иск

Ответы:

46

Если объект был создан правильно, несмотря на Intantiate()строку, выдавшую исключение, то ошибка исходит от другого экземпляра сценария - вы можете случайно получить вторую копию в вашей сцене.

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

Другой экземпляр настроен неправильно и выдает ошибку. Но если вы просто смотрите на правильно настроенный экземпляр, эта ошибка, кажется, возникла из ниоткуда и не имеет видимых последствий.

Вы можете распечатать путь к объекту при запуске - или в нулевой проверке непосредственно перед ошибочной строкой - чтобы отследить ненужные дубликаты сцены.

Вы абсолютно не должны игнорировать эту ошибку.

В лучшем случае это сжигает вычислительные циклы без необходимости. В худшем случае, это признак того, что ваша игра делает что-то, чего вы не до конца понимаете, и это может стать причиной гораздо больших проблем в будущем.

Д.М.Григорий
источник
12
+1, ошибки не совпадают с предупреждениями, если есть ошибка, вы никогда не знаете, когда она перерастет в весь сбой игры.
ТомЦагк
13
Не всегда безопасно игнорировать предупреждения. Даже если это не ошибка, это может потенциально привести к ситуации, когда игра вылетает.
Шон Бертон
2
Я согласен с @SeanBurton, игнорирование предупреждений не является безопасной практикой. Вы должны игнорировать предупреждение, если и только если вы понимаете, что его вызывает, и чувствуете, что оно не вызывает проблем в вашем коде. Даже тогда спросите себя, не могли бы вы сделать это лучше.
Джек Эйдли,
3
Каждый проект, над которым я работал с большой командой, в какой-то момент становился настолько перегруженным «игнорируемыми» предупреждениями, что начинал маскировать настоящие проблемы. Поэтому я бы определенно выступал за серьезное отношение к предупреждениям, и если это неизбежно, отключите его для соответствующей строки вместе с комментарием, четко определяющим, почему безопасно пропустить создание предупреждения.
DMGregory
1
Я на 100% сотрудничаю с @DMGregory, я работал только с очень небольшими командами, но пару раз предупреждения начинали складываться, было ужасно находить «настоящие» проблемы, или вы все время их упускали. Моя задача - поддерживать журнал в чистоте, за исключением тестирования, даже если мне нужно отключить предупреждения для кода плагинов (пожалуйста, не создавайте плагины с предупреждениями НИКОГДА), это намного лучше в долгосрочной перспективе IMO. Редактировать: чтобы быть понятным, никогда не отключайте предупреждения, если вы не уверены на 100%, что другого пути нет (что происходит в 0,001% случаев), всегда исправляйте их.
Trisibo
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);

Выяснить почему

  • Теперь немного опыта Unity говорит нам, что «Объект, который вы хотите создать, является нулевым» вызван Instantiate().
  • Итак, это означает, что prefabесть null.
  • Так что это означает, что Resources.Loadвозвращается null.
  • В документацииResources.Load сказано: « Возвращает актив, pathесли он может быть найден, иначе возвращает ноль ».
  • Так что это означает, что он не находит заданный путь (строка, которую я назвал resourceLocation)

Что-то не так с этим путем, поэтому очевидным первым шагом было бы посмотреть, что это на самом деле в конечном итоге, с Debug.Log. Поскольку «все работает как задумано», вполне вероятно, что происходит некоторое дублирование, когда одна версия работает, а другая выдает эту ошибку.

В этом случае хорошей идеей будет использование версии Debug.Log с двумя параметрами Debug.Log(resourceLocation, gameObject);. Теперь, если вы нажмете на сообщение журнала в редакторе Unity, оно выберет, GameObjectоткуда оно пришло.

Рафаэль Шмитц
источник