diff --git a/Editor/ScenePartitionSO.cs b/Editor/ScenePartitionSO.cs index 3e944ae..20bf97d 100644 --- a/Editor/ScenePartitionSO.cs +++ b/Editor/ScenePartitionSO.cs @@ -1,8 +1,12 @@ using System.Collections.Generic; +using System.IO; +using System.Linq; using UnityEditor; +using UnityEditor.SceneManagement; using UnityEngine; +using UnityEngine.SceneManagement; -namespace VertexColor.ScenePartition +namespace VertexColor.ScenePartition.Editor { [CreateAssetMenu(fileName = "Scene", menuName = "Max/ScenePartitionSO")] public class ScenePartitionSO : ScriptableObject @@ -11,13 +15,111 @@ public class ScenePartitionSO : ScriptableObject public SceneAsset sceneAsset { get; private set; } = null; public string sceneName { get; private set; } = ""; - private List loadedPartitions = new List(); + public bool hasLoadedPartitions => (loadedPartitions != null && loadedPartitions.Count > 0); + [SerializeField] + private List loadedPartitions = null; // Should not be serialized, this would be local data only. + + public void CreateScene() + { + if (sceneAsset != null) return; + + string scenePath = Path.Combine(AssetDatabase.GetAssetPath(this), $"../{this.name}.unity"); + + Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + EditorSceneManager.SaveScene(scene, scenePath); + + AssetDatabase.Refresh(); + } + + public void LoadAll() + { + string dataPath = ScenePartitionUtils.GetDataPath(this); + string scenePath = ScenePartitionUtils.GetScenePath(this); + + List data = new List(); + List files = Directory.GetFiles(dataPath).ToList(); + files.Sort(); + + for (int i = 0; i < files.Count; i++) + { + data.AddRange(File.ReadAllLines(files[i])); + } + + File.WriteAllLines(scenePath, data); + + loadedPartitions.AddRange(files); + + AssetDatabase.Refresh(); + } + + public void SaveAll() + { + if (!hasLoadedPartitions) return; + + DeleteLoadedPartitions(); + + string dataPath = ScenePartitionUtils.GetDataPath(this); + string scenePath = ScenePartitionUtils.GetScenePath(this); + + string[] data = File.ReadAllLines(scenePath); + + int lastIndex = data.Length; + for (int i = data.Length - 1; i >= 0; i--) + { + if (data[i].StartsWith("---")) // --- is the start of a new yaml document. + { + int idStartIndex = data[i].IndexOf(" &") + 2; // & is the start of the object id. + int idLength = data[i].Length; + + File.WriteAllLines($"{dataPath}/{sceneName}-{data[i][idStartIndex..idLength]}.yaml", data[i..lastIndex]); + + lastIndex = i; + } + } + + File.WriteAllLines($"{dataPath}/{sceneName}.yaml", data[0..lastIndex]); + } + + public void Unload() + { + string dataPath = ScenePartitionUtils.GetDataPath(this); + string scenePath = ScenePartitionUtils.GetScenePath(this); + + Scene scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); + + GameObject[] gameObjects = scene.GetRootGameObjects(); + + for (int i = gameObjects.Length - 1; i >= 0; i--) + { + Object.DestroyImmediate(gameObjects[i]); + } + + EditorSceneManager.SaveScene(scene); + + loadedPartitions.Clear(); + + AssetDatabase.Refresh(); + } + + private void DeleteLoadedPartitions() + { + if (loadedPartitions == null) return; + + for (int i = loadedPartitions.Count - 1; i >= 0; i--) + { + if (!File.Exists(loadedPartitions[i])) continue; + + File.Delete(loadedPartitions[i]); + } + + loadedPartitions.Clear(); + } private void OnValidate() { if (string.IsNullOrWhiteSpace(sceneName) && sceneAsset != null) { - sceneName= sceneAsset.name; + sceneName = sceneAsset.name; } } } diff --git a/Editor/ScenePartitionSOEditor.cs b/Editor/ScenePartitionSOEditor.cs index 73b39ce..fe6ff29 100644 --- a/Editor/ScenePartitionSOEditor.cs +++ b/Editor/ScenePartitionSOEditor.cs @@ -1,47 +1,59 @@ using UnityEngine; using UnityEditor; -using System.IO; namespace VertexColor.ScenePartition.Editor { [CustomEditor(typeof(ScenePartitionSO))] public class ScenePartitionSOEditor : UnityEditor.Editor { - //SerializedProperty property; - - void OnEnable() - { - //property = serializedObject.FindProperty("myProperty"); - } - public override void OnInspectorGUI() { - DrawDefaultInspector(); - ScenePartitionSO scenePartitionSO = (target as ScenePartitionSO); serializedObject.Update(); - //EditorGUILayout.PropertyField(property); + //EditorGUILayout.PropertyField(sceneAssetProperty); serializedObject.ApplyModifiedProperties(); - if (GUILayout.Button("Load")) + EditorGUILayout.Space(); + + if(scenePartitionSO.sceneAsset == null) { - ScenePartitionUtils.Load(scenePartitionSO); + if (GUILayout.Button("Create Scene")) + { + scenePartitionSO.CreateScene(); + } + } + else + { + if (GUILayout.Button("Load All")) + { + scenePartitionSO.LoadAll(); + } + + if (scenePartitionSO.hasLoadedPartitions) + { + if (GUILayout.Button("Save All")) + { + scenePartitionSO.SaveAll(); + } + } + + if (GUILayout.Button("Unload")) + { + scenePartitionSO.Unload(); + } + + if (GUILayout.Button("Open Scene Data Folder")) + { + EditorUtility.RevealInFinder(ScenePartitionUtils.GetDataPath(scenePartitionSO)); + } } - if (GUILayout.Button("Save")) - { - ScenePartitionUtils.Save(scenePartitionSO); - } + EditorGUILayout.Space(); - if (GUILayout.Button("Unload")) + using (new EditorGUI.DisabledGroupScope(true)) { - ScenePartitionUtils.Unload(scenePartitionSO); - } - - if(GUILayout.Button("Open Scene Data")) - { - EditorUtility.RevealInFinder(ScenePartitionUtils.GetDataPath(scenePartitionSO)); + DrawDefaultInspector(); } } } diff --git a/Editor/ScenePartitionUtils.cs b/Editor/ScenePartitionUtils.cs index fac3acb..d4aac7d 100644 --- a/Editor/ScenePartitionUtils.cs +++ b/Editor/ScenePartitionUtils.cs @@ -1,10 +1,6 @@ -using System.Collections.Generic; using System.IO; -using System.Linq; using UnityEditor; -using UnityEditor.SceneManagement; using UnityEngine; -using UnityEngine.SceneManagement; namespace VertexColor.ScenePartition.Editor { @@ -28,67 +24,5 @@ public static string GetScenePath(ScenePartitionSO scenePartitionSO) return scenePath; } - - public static void Load(ScenePartitionSO scenePartitionSO) - { - string dataPath = GetDataPath(scenePartitionSO); - string scenePath = GetScenePath(scenePartitionSO); - - List data = new List(); - List files = Directory.GetFiles(dataPath).ToList(); - files.Sort(); - - for (int i = 0; i < files.Count; i++) - { - data.AddRange(File.ReadAllLines(files[i])); - } - - File.WriteAllLines(scenePath, data); - - AssetDatabase.Refresh(); - } - - public static void Save(ScenePartitionSO scenePartitionSO) - { - string dataPath = GetDataPath(scenePartitionSO); - string scenePath = GetScenePath(scenePartitionSO); - - string[] data = File.ReadAllLines(scenePath); - - int lastIndex = data.Length; - for (int i = data.Length - 1; i >= 0; i--) - { - if (data[i].StartsWith("---")) // --- is the start of a new yaml document. - { - int idStartIndex = data[i].IndexOf(" &") + 2; // & is the start of the object id. - int idLength = data[i].Length; - - File.WriteAllLines($"{dataPath}/{scenePartitionSO.sceneName}-{data[i][idStartIndex..idLength]}.yaml", data[i..lastIndex]); - - lastIndex = i; - } - } - - File.WriteAllLines($"{dataPath}/{scenePartitionSO.sceneName}.yaml", data[0..lastIndex]); - } - - public static void Unload(ScenePartitionSO scenePartitionSO) - { - string dataPath = GetDataPath(scenePartitionSO); - string scenePath = GetScenePath(scenePartitionSO); - - Scene scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); - - GameObject[] gameObjects = scene.GetRootGameObjects(); - - for (int i = gameObjects.Length - 1; i >= 0; i--) - { - Object.DestroyImmediate(gameObjects[i]); - } - - EditorSceneManager.SaveScene(scene); - - AssetDatabase.Refresh(); - } } } \ No newline at end of file