0
\$\begingroup\$

I have code similar to the following in a Unity project. I was trying to shoot a projectile when spacebar was hit, but a projectile wasn't appearing. I found out the problem was caused because I moved my bullet prefab to /Assets/Resources/prefabs/bullet.prefab. Bullets started appearing upon updating the string in Resources.Load, but I then questioned why I didn't encounter some sort of runtime error when I tried to perform operations on the non-existent bullet.

if (Input.GetKeyDown(KeyCode.space))
{
    // Bullet is actually in /Assets/Resources/prefabs/bullet, so this won't find it.
    var bullet = Resources.Load("bullet") as GameObject;
    bullet.transform.position = new Vector3(0, 0, 0);
    Instantiate(bullet);
}

Could someone please tell me why Unity doesn't throw an exception or any sort of runtime error when loading a resource that doesn't exist? Maybe there are exceptions/recoveries happening but I just didn't notice because the game updates much faster than I can push the space bar?

\$\endgroup\$
  • \$\begingroup\$ I'd suggest you do not use Resources.Load but actualy assign the prefabs in the Editor. That way you do not get unexpected behavior and you are using something that exists. \$\endgroup\$ – zimspy Jul 6 '16 at 17:37
1
\$\begingroup\$

Either you weren't seeing the error, or you were experiencing a bug.

The documentation for Resources.Load says:

Returns the asset at path if it can be found otherwise returns null.

I'd expect you'd have a null pointer exception with the second line in your code block bullet.transform.position.

Since you weren't getting a null pointer, apparently Resources.Load was finding something. It could have been because you needed to rebuild, or you have another prefab named 'bullet' or some other reason.

If you didn't have the position code there before, Instantiate would produce an error saying something like "The thing you want to instantiate is null". This would just be an error message in the console, so if you're not using to looking for errors there, you might have missed it.

\$\endgroup\$
1
\$\begingroup\$

If you try to use a variable or something that is null, Unity will print an Error to its console saying something along the lines of:

"Object reference not set to instance of an object"

At which point Unity will breaks out of the method it is running and the exception is passed to the calling method. What this means in practice is that if you cause an exception to be thrown in the Start(), Update(), or pretty much any other method fundamental to MonoBehaviour, Unity will end up disabling the script, which prevents any of its other code running and potentially causing a fatal crash.

This can cause some strange behaviours when you are trying to have multiple objects interact and one or two of them aren't moving or something due to a thrown exception. But it's good because it means that you have the option of continuing on and testing other things, further investigating in that session to see what might be causing the issue, or just stopping and restarting the game to replicate the issue.

And most importantly, it means Unity itself doesn't crash, which is a nice bonus.

TL;DR - Unity DOES throw an exception, it just turns into a Debug.LogError.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.