- Home /
Scene as a variable
Is there a way to set a scene as a variable?
You can't set a scene as a variable, depening on your needs though there are other things you can do. Why did you want a variable with a scene?
You can have a string and have the name of a scene as the string value but you can't have an actual scene be a variable.
@Phles #Phles (whatever it is) Ins$$anonymous$$d of using multiple scripts to load a scene when I touch a prefab I rather use one and choose which scene I wanna load in the inspector.
Hey, The easiest way, as has been said, would be to have a string variable for the level name this could be set from the inspector and used by calling Application.LoadLevel
Or as I was bored, if you don't want to have to type the names you can use this...
A serializable class to hold level index value
[System.Serializable]
public class LevelIndex
{
public int value = 0;
}
A custom property draw for this class
using UnityEngine;
using UnityEditor;
//This file must be in Assets\Editor\
[CustomPropertyDrawer(typeof(LevelIndex))]
public class LevelIndexPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
string[] levelNames = new string[EditorBuildSettings.scenes.Length];
for (int i=0; i < EditorBuildSettings.scenes.Length; i++)
{
if (!EditorBuildSettings.scenes[i].enabled) continue;
string scenePath = EditorBuildSettings.scenes[i].path;
string[] seperators = new string[2] {"/", "."};
string[] splitPath = scenePath.Split(seperators, System.StringSplitOptions.None);
levelNames[i] = splitPath[splitPath.Length - 2];
}
EditorGUI.BeginProperty(position, label, property);
Rect rect = new Rect(position.x, position.y + position.height / 2, position.width, position.height / 2);
EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
SerializedProperty levelIndexProp = property.FindPropertyRelative("value");
int selectedLevelIndex = levelIndexProp.intValue;
selectedLevelIndex = EditorGUI.Popup(rect, "Select Level", selectedLevelIndex,levelNames);
levelIndexProp.intValue = selectedLevelIndex;
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return base.GetPropertyHeight(property, label) * 2;
}
}
This custom property drawer gets the levels from the build settings and allows selecting the level by name from a drop down list.
Now you can have something like this..
public class SomeComponent : $$anonymous$$onoBehaviour
{
public LevelIndex levelIndex;
void Update()
{
if (somethingHasHappened)
{
Application.LoadLevel(levelIndex.value);
}
}
}
The inspector for components with a LevelIndex
variable, will now show with the custom property drawer allowing you to select the level from a drop down and use it as above.
Answer by JohannesMP · Aug 14, 2018 at 06:53 AM
Just storing a path string (as the SceneAsset documentation suggests) is inadequate for production, because if the scene file is renamed you've lost your reference. We can use an Object reference to the SceneAsset but we no longer have access to AssetDatabase to look up the path when not in editor.
To reliably handle both file renames and runtime paths you need two serialized pieces of data (Object reference in editor, string path at runtime). You can create a SceneReference object that uses ISerializationCallbackReceiver to ensure that the stored path is always valid based on the specified SceneAsset Object.
As an example, here is my approach to this problem: https://gist.github.com/JohannesMP/ec7d3f0bcf167dab3d0d3bb480e0e07b
Features
Custom PropertyDrawer that displays the current Build Settings status, including BuildIndex and convenient buttons for managing it with destructive action confirmation dialogues.
If (and only if) the serialized Object reference is invalid but path is still valid (for example if someone merged incorrectly) will recover object using path.
Buttons collapse to smaller text if full text cannot be displayed.
Includes detailed tooltips and respects Version Control if build settings is not checked out (tested with Perforce)
Answer by nitroxis · May 17, 2016 at 12:57 PM
You can use a scene as
using UnityEngine.SceneManagement;
public Object sceneToLoad;
and then load the scene / or whatever you want to do with it like
SceneManager.LoadScene(sceneToLoad.name);
This works for me when running in editor but not when building (only tried for standalone). I guess the reference to a scene does not get properly serialized in the build somehow. Did you experience the same behvaiour?
Answer by tanoshimi · Dec 29, 2013 at 06:40 PM
Scenes can generally be referred to by name (e.g. in Application.LoadLevel), so you can probably use a string variable to hold the name of the scene in question.
Answer by Raven-Rock · Dec 29, 2013 at 08:48 PM
try something like this. You would likely want the level array to be visible in the inspector so you would want it outside of the function but for simplicity sake in showing the example I have it inside the function.
public void chooseLevel(int _levelArrayIdx)
{
string[] levels = new string[]{"Level1","Level2","Level3"};
Application.LoadLevel(levels[_levelArrayIdx]);
}
Answer by Xx_Link_xX · Jan 13, 2017 at 11:00 AM
So this is an old post, but i figured people are still looking for an answer here. I recently came across this:
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameStarter : MonoBehaviour
{
public SceneAsset offlineScene;
private void Awake()
{
if (GameObject.FindGameObjectWithTag("NetworkManager") == null)
SceneManager.LoadScene(offlineScene.name);
}
}
Just make sure you are using UnityEditor. @Derpyness
Looks like I failed to further test this implementation. When building your game with this set, you will get compile errors looking for UnityEditor.
You can load scenes using strings, I'll write an answer later today
I know I am late to the game but this is really good. i am just starting out and I love this Script
Your answer
Follow this Question
Related Questions
save variable from scene to scene 2 Answers
Storing scene-specific variables? 1 Answer
how to get other script variable from other scene? 3 Answers
Calling a scene with a variable 1 Answer
Instantiate new object from scratch 1 Answer