309 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			309 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
|  | using System.Collections; | |||
|  | using System.Collections.Generic; | |||
|  | using UnityEngine; | |||
|  | using UnityEditor; | |||
|  | using ES3Internal; | |||
|  | 
 | |||
|  | namespace ES3Editor | |||
|  | { | |||
|  | 	[System.Serializable] | |||
|  | 	public class AutoSaveWindow : SubWindow | |||
|  | 	{ | |||
|  | 		public bool showAdvancedSettings = false; | |||
|  | 
 | |||
|  | 		public ES3AutoSaveMgr mgr = null; | |||
|  | 
 | |||
|  |         private HierarchyItem[] hierarchy = null; | |||
|  |         public HierarchyItem selected = null; | |||
|  | 
 | |||
|  |         private Vector2 hierarchyScrollPosition = Vector2.zero; | |||
|  | 
 | |||
|  |         private bool sceneOpen = true; | |||
|  | 
 | |||
|  |         private string searchTerm = ""; | |||
|  | 
 | |||
|  |         public AutoSaveWindow(EditorWindow window) : base("Auto Save", window){} | |||
|  | 
 | |||
|  | 		public override void OnGUI() | |||
|  | 		{ | |||
|  | 			Init(); | |||
|  | 
 | |||
|  | 			if(mgr == null) | |||
|  | 			{ | |||
|  |                 EditorGUILayout.Space(); | |||
|  |                 if (GUILayout.Button("Enable Auto Save for this scene")) | |||
|  |                     mgr = ES3Postprocessor.AddManagerToScene().GetComponent<ES3AutoSaveMgr>(); | |||
|  |                 else | |||
|  |                     return; | |||
|  | 			} | |||
|  | 
 | |||
|  | 			var style = EditorStyle.Get; | |||
|  | 
 | |||
|  |             using (var changeCheck = new EditorGUI.ChangeCheckScope()) | |||
|  |             { | |||
|  |                 using (var vertical = new EditorGUILayout.VerticalScope(style.areaPadded)) | |||
|  |                 { | |||
|  |                     //GUILayout.Label("Settings for current scene", style.heading); | |||
|  |                     mgr.saveEvent = (ES3AutoSaveMgr.SaveEvent)EditorGUILayout.EnumPopup("Save Event", mgr.saveEvent); | |||
|  |                     mgr.loadEvent = (ES3AutoSaveMgr.LoadEvent)EditorGUILayout.EnumPopup("Load Event", mgr.loadEvent); | |||
|  | 
 | |||
|  |                     EditorGUILayout.Space(); | |||
|  | 
 | |||
|  |                     showAdvancedSettings = EditorGUILayout.Foldout(showAdvancedSettings, "Show Advanced Settings"); | |||
|  |                     if (showAdvancedSettings) | |||
|  |                     { | |||
|  |                         EditorGUI.indentLevel++; | |||
|  |                         mgr.key = EditorGUILayout.TextField("Key", mgr.key); | |||
|  |                         ES3SettingsEditor.Draw(mgr.settings); | |||
|  |                         EditorGUI.indentLevel--; | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 // Display the menu. | |||
|  |                 using (var horizontal = new EditorGUILayout.HorizontalScope()) | |||
|  |                 { | |||
|  |                     if (GUILayout.Button("Scene", sceneOpen ? style.menuButtonSelected : style.menuButton)) | |||
|  |                     { | |||
|  |                         sceneOpen = true; | |||
|  |                         OnFocus(); | |||
|  |                     } | |||
|  |                     if (GUILayout.Button("Prefabs", sceneOpen ? style.menuButton : style.menuButtonSelected)) | |||
|  |                     { | |||
|  |                         sceneOpen = false; | |||
|  |                         OnFocus(); | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 //EditorGUILayout.HelpBox("Select the Components you want to be saved.\nTo maximise performance, only select the Components with variables which need persisting.", MessageType.None, true); | |||
|  | 
 | |||
|  |                 if (hierarchy == null || hierarchy.Length == 0) | |||
|  |                 { | |||
|  |                     EditorGUILayout.LabelField("Right-click a prefab and select 'Easy Save 3 > Enable Easy Save for Scene' to enable Auto Save for it.\n\nYour scene will also need to reference this prefab for it to be recognised.", style.area); | |||
|  |                     return; | |||
|  |                 } | |||
|  | 
 | |||
|  |                 using (var scrollView = new EditorGUILayout.ScrollViewScope(hierarchyScrollPosition, style.areaPadded)) | |||
|  |                 { | |||
|  |                     hierarchyScrollPosition = scrollView.scrollPosition; | |||
|  | 
 | |||
|  |                     using (new EditorGUILayout.HorizontalScope(GUILayout.Width(200))) | |||
|  |                     { | |||
|  |                         searchTerm = GUILayout.TextField(searchTerm, GUI.skin.FindStyle("ToolbarSeachTextField")); | |||
|  |                         if (GUILayout.Button("", GUI.skin.FindStyle("ToolbarSeachCancelButton"))) | |||
|  |                         { | |||
|  |                             // Remove focus if cleared | |||
|  |                             searchTerm = ""; | |||
|  |                             GUI.FocusControl(null); | |||
|  |                         } | |||
|  |                     } | |||
|  | 
 | |||
|  |                     EditorGUILayout.Space(); | |||
|  |                     EditorGUILayout.Space(); | |||
|  | 
 | |||
|  |                     foreach (var go in hierarchy) | |||
|  |                         if (go != null) | |||
|  |                             go.DrawHierarchy(searchTerm.ToLowerInvariant()); | |||
|  |                 } | |||
|  |                 if (changeCheck.changed) | |||
|  |                     EditorUtility.SetDirty(mgr); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  | 		public void Init() | |||
|  | 		{ | |||
|  |             if (mgr == null) | |||
|  |             { | |||
|  |                 var mgrs = Resources.FindObjectsOfTypeAll<ES3AutoSaveMgr>(); | |||
|  |                 if (mgrs.Length > 0) | |||
|  |                     mgr = mgrs[0]; | |||
|  |             } | |||
|  | 
 | |||
|  |             if (hierarchy == null) | |||
|  |                 OnFocus(); | |||
|  |         } | |||
|  | 
 | |||
|  |         public override void OnFocus() | |||
|  |         { | |||
|  | 
 | |||
|  |             GameObject[] parentObjects; | |||
|  |             if (sceneOpen) | |||
|  |                 parentObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects(); | |||
|  |             else // Prefabs | |||
|  |             { | |||
|  |                 var prefabs = ES3ReferenceMgr.Current.prefabs; | |||
|  |                 parentObjects = new GameObject[prefabs.Count]; | |||
|  |                 for (int i = 0; i < prefabs.Count; i++) | |||
|  |                     if(prefabs[i] != null) | |||
|  |                         parentObjects[i] = prefabs[i].gameObject; | |||
|  |             } | |||
|  |             hierarchy = new HierarchyItem[parentObjects.Length]; | |||
|  |             for (int i = 0; i < parentObjects.Length; i++) | |||
|  |                 if(parentObjects[i] != null) | |||
|  |                     hierarchy[i] = new HierarchyItem(parentObjects[i].transform, null, this); | |||
|  |         } | |||
|  | 
 | |||
|  |         public class HierarchyItem | |||
|  |         { | |||
|  |             private ES3AutoSave autoSave; | |||
|  |             private Transform t; | |||
|  |             private Component[] components = null; | |||
|  |             // Immediate children of this GameObject | |||
|  |             private HierarchyItem[] children = new HierarchyItem[0]; | |||
|  |             private bool showComponents = false; | |||
|  |             //private AutoSaveWindow window; | |||
|  | 
 | |||
|  |             public HierarchyItem(Transform t, HierarchyItem parent, AutoSaveWindow window) | |||
|  |             { | |||
|  |                 this.autoSave = t.GetComponent<ES3AutoSave>(); | |||
|  |                 this.t = t; | |||
|  |                 this.components = t.GetComponents<Component>(); | |||
|  | 
 | |||
|  |                 children = new HierarchyItem[t.childCount]; | |||
|  |                 for (int i = 0; i < t.childCount; i++) | |||
|  |                     children[i] = new HierarchyItem(t.GetChild(i), this, window); | |||
|  | 
 | |||
|  |                 //this.window = window; | |||
|  |             } | |||
|  | 
 | |||
|  |             public void MergeDown(ES3AutoSave autoSave) | |||
|  |             { | |||
|  |                 if (this.autoSave != autoSave) | |||
|  |                 { | |||
|  |                     if (this.autoSave != null) | |||
|  |                     { | |||
|  |                         autoSave.componentsToSave.AddRange(autoSave.componentsToSave); | |||
|  |                         Object.DestroyImmediate(this.autoSave); | |||
|  |                     } | |||
|  |                     this.autoSave = autoSave; | |||
|  |                 } | |||
|  | 
 | |||
|  |                 foreach (var child in children) | |||
|  |                     MergeDown(autoSave); | |||
|  |             } | |||
|  | 
 | |||
|  |             public void DrawHierarchy(string searchTerm) | |||
|  |             { | |||
|  |                 bool containsSearchTerm = false; | |||
|  |                 if (t != null) | |||
|  |                 { | |||
|  |                     if (containsSearchTerm = t.name.ToLowerInvariant().Contains(searchTerm)) | |||
|  |                     { | |||
|  |                         GUIContent saveIcon; | |||
|  |                         EditorGUIUtility.SetIconSize(new Vector2(16, 16)); | |||
|  | 
 | |||
|  |                         if (HasSelectedComponents()) | |||
|  |                             saveIcon = new GUIContent(t.name, EditorStyle.Get.saveIconSelected, "There are Components on this GameObject which will be saved."); | |||
|  |                         else | |||
|  |                             saveIcon = new GUIContent(t.name, EditorStyle.Get.saveIconUnselected, "No Components on this GameObject will be saved"); | |||
|  | 
 | |||
|  |                         GUIStyle style = GUI.skin.GetStyle("Foldout"); | |||
|  |                         if (Selection.activeTransform == t) | |||
|  |                         { | |||
|  |                             style = new GUIStyle(style); | |||
|  |                             style.fontStyle = FontStyle.Bold; | |||
|  |                         } | |||
|  | 
 | |||
|  |                         var open = EditorGUILayout.Foldout(showComponents, saveIcon, style); | |||
|  |                         if (open) | |||
|  |                         { | |||
|  |                             // Ping the GameObject if this was previously closed | |||
|  |                             if (showComponents != open) | |||
|  |                                 EditorGUIUtility.PingObject(t.gameObject); | |||
|  |                             DrawComponents(); | |||
|  |                         } | |||
|  |                         showComponents = open; | |||
|  | 
 | |||
|  |                         EditorGUI.indentLevel += 1; | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 // Draw children | |||
|  |                 if(children != null) | |||
|  |                     foreach (var child in children) | |||
|  |                         if(child != null) | |||
|  |                             child.DrawHierarchy(searchTerm); | |||
|  | 
 | |||
|  |                 if(containsSearchTerm) | |||
|  |                     EditorGUI.indentLevel-=1; | |||
|  |             } | |||
|  | 
 | |||
|  |             public void DrawComponents() | |||
|  |             { | |||
|  |                 EditorGUI.indentLevel+=3; | |||
|  |                 using (var scope = new EditorGUILayout.VerticalScope()) | |||
|  |                 { | |||
|  |                     bool toggle; | |||
|  |                     toggle = EditorGUILayout.ToggleLeft("active", autoSave != null ? autoSave.saveActive : false); | |||
|  |                     if((autoSave = (toggle && autoSave == null) ? t.gameObject.AddComponent<ES3AutoSave>() : autoSave) != null) | |||
|  |                         autoSave.saveActive = toggle; | |||
|  | 
 | |||
|  |                     toggle = EditorGUILayout.ToggleLeft("hideFlags", autoSave != null ? autoSave.saveHideFlags : false); | |||
|  |                     if ((autoSave = (toggle && autoSave == null) ? t.gameObject.AddComponent<ES3AutoSave>() : autoSave) != null) | |||
|  |                         autoSave.saveHideFlags = toggle; | |||
|  | 
 | |||
|  |                     toggle = EditorGUILayout.ToggleLeft("layer", autoSave != null ? autoSave.saveLayer : false); | |||
|  |                     if ((autoSave = (toggle && autoSave == null) ? t.gameObject.AddComponent<ES3AutoSave>() : autoSave) != null) | |||
|  |                         autoSave.saveLayer = toggle; | |||
|  | 
 | |||
|  |                     toggle = EditorGUILayout.ToggleLeft("name", autoSave != null ? autoSave.saveName : false); | |||
|  |                         if ((autoSave = (toggle && autoSave == null) ? t.gameObject.AddComponent<ES3AutoSave>() : autoSave) != null) | |||
|  |                         autoSave.saveName = toggle; | |||
|  | 
 | |||
|  |                     toggle = EditorGUILayout.ToggleLeft("tag", autoSave != null ? autoSave.saveTag : false); | |||
|  |                     if ((autoSave = (toggle && autoSave == null) ? t.gameObject.AddComponent<ES3AutoSave>() : autoSave) != null) | |||
|  |                         autoSave.saveTag = toggle; | |||
|  | 
 | |||
|  |                     foreach (var component in components) | |||
|  |                     { | |||
|  |                         if (component == null) | |||
|  |                             continue; | |||
|  | 
 | |||
|  |                         using (var horizontalScope = new EditorGUILayout.HorizontalScope()) | |||
|  |                         { | |||
|  |                             bool saveComponent = false; | |||
|  |                             if (autoSave != null) | |||
|  |                                 saveComponent = autoSave.componentsToSave.Contains(component); | |||
|  | 
 | |||
|  |                             var newValue = EditorGUILayout.ToggleLeft(EditorGUIUtility.ObjectContent(component, component.GetType()), saveComponent); | |||
|  |                             // If the checkbox has changed, we want to save or not save a Component | |||
|  |                             if (newValue != saveComponent) | |||
|  |                             { | |||
|  |                                 if (autoSave == null) | |||
|  |                                 { | |||
|  |                                     autoSave = t.gameObject.AddComponent<ES3AutoSave>(); | |||
|  |                                     autoSave.saveChildren = false; | |||
|  |                                 } | |||
|  |                                 // If we've unchecked the box, remove the Component from the array. | |||
|  |                                 if (newValue == false) | |||
|  |                                     autoSave.componentsToSave.Remove(component); | |||
|  |                                 // Else, add it to the array. | |||
|  |                                 else | |||
|  |                                     autoSave.componentsToSave.Add(component); | |||
|  |                             } | |||
|  |                             if(GUILayout.Button(EditorGUIUtility.IconContent("_Popup"), new GUIStyle("Label"))) | |||
|  |                                 ES3Window.InitAndShowTypes(component.GetType()); | |||
|  |                         } | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 if(autoSave != null && (autoSave.componentsToSave == null || autoSave.componentsToSave.Count == 0) && !autoSave.saveActive && !autoSave.saveChildren && !autoSave.saveHideFlags && !autoSave.saveLayer && !autoSave.saveName && !autoSave.saveTag) | |||
|  |                 { | |||
|  |                     Undo.DestroyObjectImmediate(autoSave); | |||
|  |                     autoSave = null; | |||
|  |                 } | |||
|  |                 EditorGUI.indentLevel-=3; | |||
|  |             } | |||
|  | 
 | |||
|  |             public bool HasSelectedComponents() | |||
|  |             { | |||
|  |                 if (autoSave != null) | |||
|  |                     foreach (var component in components) | |||
|  |                         if (component != null && autoSave.componentsToSave.Contains(component)) | |||
|  |                             return true; | |||
|  |                 return false; | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  | } |