Last active
August 29, 2015 14:19
-
-
Save thebeardphantom/08b909102703d8168594 to your computer and use it in GitHub Desktop.
SceneLoader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Linq; | |
using UnityEngine; | |
namespace Rubycone.Utils { | |
public delegate void LoadComplete(GameObject loaded); | |
public class SceneLoader : MonoBehaviour { | |
public event LoadComplete LoadComplete; | |
public AsyncOperation operation { get; private set; } | |
public Coroutine loadRoutine { get; private set; } | |
public SceneVar scene { get; private set; } | |
Transform temp; | |
bool running; | |
public static SceneLoader Create(SceneVar scene) { | |
var loader = new GameObject("SCENELOADER_" + System.Guid.NewGuid().ToString()).AddComponent<SceneLoader>(); | |
GameObject.DontDestroyOnLoad(loader.gameObject); | |
loader.scene = scene; | |
return loader; | |
} | |
public static SceneLoader[] Create(params SceneVar[] scenes) { | |
var loaders = new SceneLoader[scenes.Length]; | |
for(int i = 0; i < scenes.Length; i++) { | |
loaders[i] = Create(scenes[i]); | |
} | |
return loaders; | |
} | |
public void Load() { | |
if(running) { | |
return; | |
} | |
running = true; | |
loadRoutine = StartCoroutine(_Load()); | |
} | |
public void LoadAsync() { | |
if(running) { | |
return; | |
} | |
running = true; | |
loadRoutine = StartCoroutine(_LoadAsync()); | |
} | |
public void LoadAdditive() { | |
if(running) { | |
return; | |
} | |
running = true; | |
loadRoutine = StartCoroutine(_LoadAdditive()); | |
} | |
public void LoadAdditiveAsync() { | |
if(running) { | |
return; | |
} | |
running = true; | |
loadRoutine = StartCoroutine(_LoadAdditiveAsync()); | |
} | |
IEnumerator _Load() { | |
Application.LoadLevel(scene.index); | |
yield return null; | |
var newSceneRoot = ParentNewSceneTransforms(); | |
if(LoadComplete != null) { | |
LoadComplete(newSceneRoot); | |
} | |
running = false; | |
Destroy(gameObject); | |
} | |
IEnumerator _LoadAsync() { | |
operation = Application.LoadLevelAsync(scene.index); | |
yield return operation; | |
var newSceneRoot = ParentNewSceneTransforms(); | |
if(LoadComplete != null) { | |
LoadComplete(newSceneRoot); | |
} | |
running = false; | |
Destroy(gameObject); | |
} | |
IEnumerator _LoadAdditive() { | |
StoreCurrent(); | |
Application.LoadLevelAdditive(scene.index); | |
yield return null; | |
var newSceneRoot = ParentNewSceneTransforms(); | |
UnloadTemp(); | |
if(LoadComplete != null) { | |
LoadComplete(newSceneRoot); | |
} | |
running = false; | |
Destroy(gameObject); | |
} | |
IEnumerator _LoadAdditiveAsync() { | |
StoreCurrent(); | |
operation = Application.LoadLevelAdditiveAsync(scene.index); | |
yield return operation; | |
var newSceneRoot = ParentNewSceneTransforms(); | |
UnloadTemp(); | |
if(LoadComplete != null) { | |
LoadComplete(newSceneRoot); | |
} | |
running = false; | |
Destroy(gameObject); | |
} | |
/// <summary> | |
/// Unloads temp storage. | |
/// </summary> | |
/// <param name="temp"></param> | |
void UnloadTemp() { | |
for(int i = 0; i < temp.childCount; i++) { | |
temp.GetChild(i).parent = null; | |
} | |
Destroy(temp.gameObject); | |
} | |
/// <summary> | |
/// Stores all root-level transforms from the newly loaded scene to a transform. | |
/// </summary> | |
/// <returns>The new temp parent transform</returns> | |
GameObject ParentNewSceneTransforms() { | |
var roots = FindObjectsOfType<Transform>().Where(t => t.parent == null); | |
var newRoot = new GameObject(scene.name); | |
foreach(var r in roots) { | |
r.parent = newRoot.transform; | |
} | |
return newRoot; | |
} | |
/// <summary> | |
/// Stores all current root-level transforms to a temp transform | |
/// </summary> | |
/// <returns>The new temp parent transform</returns> | |
void StoreCurrent() { | |
var roots = FindObjectsOfType<Transform>().Where(t => t.parent == null); | |
temp = new GameObject("SL_TEMP_STORAGE_" + System.Guid.NewGuid().ToString()).transform; | |
foreach(var r in roots) { | |
r.parent = temp; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Rubycone.Utils { | |
[System.Serializable] | |
public class SceneVar { | |
public string path = string.Empty; | |
public string name = string.Empty; | |
public int index; | |
public SceneVar() { } | |
public SceneVar(string name) { | |
this.name = name; | |
} | |
public SceneVar(int index) { | |
this.index = index; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
namespace Rubycone.Utils { | |
[CustomPropertyDrawer(typeof(SceneVar))] | |
public class SceneVarEditor : PropertyDrawer { | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { | |
var levelNames = new string[EditorBuildSettings.scenes.Length]; | |
for(int i=0; i < EditorBuildSettings.scenes.Length; i++) { | |
if(!EditorBuildSettings.scenes[i].enabled) { | |
continue; | |
} | |
var scenePath = EditorBuildSettings.scenes[i].path; | |
var seperators = new string[2] { "/", "." }; | |
var splitPath = scenePath.Split(seperators, System.StringSplitOptions.None); | |
levelNames[i] = splitPath[splitPath.Length - 2]; | |
} | |
EditorGUI.BeginProperty(position, label, property); | |
var levelIndexProp = property.FindPropertyRelative("index"); | |
var levelPath = property.FindPropertyRelative("path"); | |
var levelName = property.FindPropertyRelative("name"); | |
int selectedLevelIndex = levelIndexProp.intValue; | |
selectedLevelIndex = EditorGUI.Popup(position, label.text, selectedLevelIndex, levelNames); | |
levelIndexProp.intValue = selectedLevelIndex; | |
levelPath.stringValue = EditorBuildSettings.scenes[selectedLevelIndex].path; | |
levelName.stringValue = levelNames[selectedLevelIndex]; | |
EditorGUI.EndProperty(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Place SceneVarEditor in an Editor folder, other scripts can go anywhere.