So as to not hardcode the Scene names, I wanted a public variable to hold them. In the editor, everything works flawlessly, however once the game is compiled, Object.name doesn’t return a value.
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneLoadTest : MonoBehaviour {
public Object scene;
public Text text;
void Update() {
text.text = scene.name;
if (scene == null) text.text = "Scene is NULL!";
if (Input.GetKey(KeyCode.Keypad0)) {
SceneManager.LoadScene(scene.name);
}
}
}
With this code, the Text retains its default value (the one assigned in the inspector), instead of changing to the name of the Scene. I’ve tried using different objects and found that Sprites and Sounds work fine, which indicates this is an issue with the Scene Asset after compilation.
I’m using Unity version 2020.3.0f1 and have also noted this issue in version 2020.1.2f1.
So what are you actually referencing in the inspector with that Object scene field? Did you create some random Sprite or something with the scene name as its name?
It’s unfortunate that Scenes are not considered Assets in unity, and they are not directly serializable the way other assets are. To get around this a lot of people just use strings with the scene name.
Ok apparently I’m mistaken about there not being a Scene Asset:
The problem is - SceneAsset is part of the UnityEditor namespace. You cannot use anything from UnityEditor in a build. That’s why it’s only working in the editor. You have to ultimately just use a string to serialize a reference to your scene.
Regardless of what it is, Unity Inspector allows it to slot into an Object field. It works in the editor, but not in the final build, yet is not specifically stated to be an editor-only item. In the final build, the Object does not return a null, meaning it is assigned, but its name cannot be called. Regardless how I look at it, it’s still a bug.
It’s called a “Scene Asset” in the inspector window, just like a Sprite is called “Texture 2D” or a sound “Audio Clip”, but I’m not using it as a Scene Asset, I’m using it as a generic Object, that it extends.
To clarify, a “Scene Asset” is a “.unity” file that is used to load a level and even in that link you gave it clearly states “inherits from:Object”.
But it is specifically stated to be an editor only item:
You are using UnityEngine.Object in your script, which means you are not explicitly using UnityEditor;, but that doesn’t change the fact that you are using a UnityEditor type.
If you look at the doc page for SceneAsset, they include an example for how to use a SceneAsset properly that will work in a build. I do wish you could just straight up use SceneAsset without jumping through hoops.
Yes the compiler will let you do it. But the SceneAsset class literally does not exist in your build. The variable type may be Object, but the actual object is of type SceneAsset. Editor types do not get packaged into your build.
Why do you think you’re having to jump through this hoop of using a plain Object field in the first place? That alone should tip you off something is not right. I’m guessing you tried to use SceneAsset, and then your game would not build, so you tried to “fix it” by changing the reference to Object?
Since I cast it as an Object, then it is an Object and all other properties are lost in the cast. Like casting a Vector3 to a Vector2. It is no longer a Scene Asset, but an Object that inherits some properties of the original. Like the name, that I need. I’m not trying to use it load a scene, I’m trying to use it to extract a string, which I can then use to load a scene.
I’m not even sure we’re talking about the same Scene Asset. The one I’m referring to is this:
Not typeof, not as. Not even a struct, but an actual Asset.
I understand what you are trying to do, but your understanding of how object references work in C# is mistaken. When you cast a reference to a reference type such as UnityEngine.Object or System.object or SceneAsset, the object itself is not changed. You are merely changing the lens through which you are viewing the object. The fields are still there, you just can’t access them through that variable. It is still a SceneAsset, even though you are viewing it through the lens of Object.
Additionally, because Vector3 and Vector2 are structs, they are value types. This means assigning the value to a variable actually copies the object, and in this case with this conversion, it discards the z component. The main point though is that a copy is created, which is not the case for reference types like UnityEngine.Object and SceneAsset.