Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@FlaShG
Created May 7, 2023 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FlaShG/2f94f79105964592224277884bf82e67 to your computer and use it in GitHub Desktop.
Save FlaShG/2f94f79105964592224277884bf82e67 to your computer and use it in GitHub Desktop.
A serializable struct for referencing and, at runtime, handle scenes.
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.SceneManagement;
[System.Serializable]
public struct RuntimeSceneReference : ISerializationCallbackReceiver
{
#if UNITY_EDITOR
internal static class PropertyNames
{
internal const string sceneAsset = nameof(RuntimeSceneReference.sceneAsset);
}
#endif
[SerializeField, HideInInspector]
private string sceneName;
#if UNITY_EDITOR
[SerializeField]
private SceneAsset sceneAsset;
#endif
/// <summary>
/// Loads the scene if it isn't loaded yet.
/// </summary>
public void LoadSingle(LoadSceneMode mode = LoadSceneMode.Single)
{
if (SceneIsLoaded()) return;
SceneManager.LoadScene(sceneName, mode);
}
/// <summary>
/// Loads the scene if it isn't loaded yet.
/// </summary>
public AsyncOperation LoadSingleAsync(LoadSceneMode mode = LoadSceneMode.Single)
{
if (SceneIsLoaded()) return null;
return SceneManager.LoadSceneAsync(sceneName, mode);
}
public AsyncOperation Unload()
{
if (!SceneIsLoaded()) return null;
return SceneManager.UnloadSceneAsync(sceneName);
}
private bool SceneIsLoaded()
{
return SceneManager.GetSceneByName(sceneName).isLoaded;
}
public bool SetAsActiveScene()
{
var scene = SceneManager.GetSceneByName(sceneName);
return SceneManager.SetActiveScene(scene);
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
#if UNITY_EDITOR
sceneName = sceneAsset != null ? sceneAsset.name : null;
#endif
}
}
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(RuntimeSceneReference))]
public class RuntimeSceneReferenceDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
property = property.FindPropertyRelative(RuntimeSceneReference.PropertyNames.sceneAsset);
var sceneAsset = (SceneAsset)property.objectReferenceValue;
if (sceneAsset != null)
{
var isInBuildList = IsInBuildList(sceneAsset);
if (!isInBuildList)
{
const int labelRectWidth = 100;
GUI.color = new Color(1f, 0.4f, 0.4f, 1f);
var labelRect = new Rect(position.x + position.width - labelRectWidth, position.y, labelRectWidth, position.height);
GUI.Box(labelRect, "Not in Build List!");
position.xMax -= labelRectWidth + 3;
}
}
EditorGUI.PropertyField(position, property, label);
GUI.color = Color.white;
}
private static bool IsInBuildList(SceneAsset sceneAsset)
{
foreach (var scene in EditorBuildSettings.scenes)
{
if (scene.path == AssetDatabase.GetAssetPath(sceneAsset) && scene.enabled)
{
return true;
}
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment