#if UNITY_EDITOR using UnityEngine; using UnityEditor; using System.Linq; using System.Collections.Generic; using UnityEditor.SceneManagement; namespace EModules { [InitializeOnLoad] public static class AutoSaveHandler { static CachedFloat __m_saveInterval = new CachedFloat("EModules/AutoSave/auto2", 5); static float m_saveInterval { get { return (float)__m_saveInterval * 60; } set { __m_saveInterval.Set( value / 60 ); ; } } static CachedBool m_debug = new CachedBool("EModules/AutoSave/auto3", false); static float? launchTime; static CachedBool m_enable= new CachedBool("EModules/AutoSave/enablesave", true); static CachedInt m_filesCount= new CachedInt("EModules/AutoSave/auto1", 10); static CachedFloat __lastSave = new CachedFloat("EModules/AutoSave/nextsave", 0); static float lastSave { get { return (float)__lastSave; } set { __lastSave.Set( value ); ; } } static float EDITOR_TIMER { get { return (float)(EditorApplication.timeSinceStartup % 1000000); } } static string AutoSaveFolder { get { return string.IsNullOrEmpty( GET_STRING( "Auto-Save Location" ) ) ? "AutoSave" : GET_STRING( "Auto-Save Location" ); } set { SET_STRING( "Auto-Save Location" , value ); } } static string autoSaveFileName { get { if ( !System.IO.Directory.Exists( Application.dataPath + "/" + AutoSaveFolder ) ) { System.IO.Directory.CreateDirectory( Application.dataPath + "/" + AutoSaveFolder ); AssetDatabase.Refresh(); } //if (!AssetDatabase.IsValidFolder("Assets/" + AutoSaveFolder)) AssetDatabase.CreateFolder("Assets", AutoSaveFolder); var files = System.IO.Directory.GetFiles(Application.dataPath + "/" + AutoSaveFolder).Select(f => f.Replace('\\', '/')).Where(f => f.EndsWith(".unity") && f.Substring(f.LastIndexOf('/') + 1).StartsWith("AutoSave")).ToArray(); if ( files.Length == 0 ) return "AutoSave_00"; var times = files.Select(System.IO.File.GetCreationTime).ToList(); var max = times.Max(); var ind = times.IndexOf(max); var count = 0; files = files.Select( n => n.Remove( n.LastIndexOf( '.' ) ) ).ToArray(); if ( int.TryParse( files[ind].Substring( files[ind].Length - 2 ) , out count ) ) { count = (count + 1) % m_filesCount; return "AutoSave_" + count.ToString( "D2" ); } return "AutoSave_00"; } } //* INITIALIZATION *// static AutoSaveHandler() { EditorApplication.update -= UpdateCS; EditorApplication.update += UpdateCS; resetSet(); } static void resetSet() { // if ( !HAS_KEY( "enablesave" ) ) SET_INT( "enablesave" , 1 ); // m_enable = GET_INT( "enablesave" ) == 1; // if ( HAS_KEY( "auto1" ) ) { // m_filesCount = GET_INT( "auto1" ); // m_saveInterval = GET_INT( "auto2" ) * 60; // m_debug = GET_BOOL( "auto3" ); } //* INITIALIZATION *// //#if UNITY_2018_3_OR_NEWER #if !UNITY_2018_3_OR_NEWER [PreferenceItem( "Auto-Save" )] public static void OnPreferencesGUI() { _OnPreferencesGUI( null ); } #else [SettingsProvider] static SettingsProvider MyNewPrefCode0() { var p = new MyPrefSettingsProvider("Preferences/Auto-Save" ,SettingsScope.User ); p.keywords = new[] { "AutoSaveAuto SaveEmodulesei" }; return p; } private class MyPrefSettingsProvider : SettingsProvider { public MyPrefSettingsProvider( string path , SettingsScope scopes = SettingsScope.User ) : base( path , scopes ) { } public override void OnGUI( string searchContext ) { _OnPreferencesGUI( searchContext ); } } #endif //* GUI *// public static void _OnPreferencesGUI( string searchContext ) { EditorGUILayout.LabelField( "Assets/" + AutoSaveFolder + " - Auto-Save Location" ); var R = EditorGUILayout.GetControlRect(GUILayout.Height(30)); GUI.Box( R , "" ); R.x += 7; R.y += 7; m_enable.Set( EditorGUI.ToggleLeft( R , "Enable" , m_enable ) ); GUI.enabled = m_enable; m_filesCount.Set( Mathf.Clamp( EditorGUILayout.IntField( "Maximum Files Version" , m_filesCount ) , 1 , 99 ) ); m_saveInterval = Mathf.Clamp( EditorGUILayout.IntField( "Save Every (Minutes)" , (int)(m_saveInterval / 60) ) , 1 , 60 ) * 60; var location = EditorGUILayout.TextField("Location", AutoSaveFolder).Replace('\\', '/'); if ( location.IndexOfAny( System.IO.Path.GetInvalidPathChars() ) >= 0 ) location = AutoSaveFolder; m_debug.Set( EditorGUILayout.Toggle( "Log" , m_debug ) ); if ( GUI.changed ) { AutoSaveFolder = location; /*SET_INT( "enablesave" , m_enable ? 1 : 0 ); SET_INT( "auto1" , m_filesCount ); SET_INT( "auto2" , (int)(m_saveInterval / 60) ); SET_BOOL( "auto3" , m_debug );*/ lastSave = (float)EDITOR_TIMER; resetSet(); } GUI.enabled = true; } //* GUI *// static float speeder = 0; //* UPDATER *// public static void UpdateCS() { if ( !m_enable ) return; if ( Application.isPlaying ) { if ( launchTime == null ) launchTime = EDITOR_TIMER; return; } if ( launchTime != null ) { lastSave += (float)(EDITOR_TIMER - launchTime.Value); launchTime = null; } if ( Mathf.Abs( speeder - EDITOR_TIMER ) < 4 ) return; speeder = EDITOR_TIMER; if ( Mathf.Abs( lastSave - (float)EDITOR_TIMER ) >= m_saveInterval * 2 ) { lastSave = (float)EDITOR_TIMER; resetSet(); } if ( Mathf.Abs( lastSave - (float)EDITOR_TIMER ) >= m_saveInterval ) { SaveScene(); EditorApplication.update -= UpdateCS; EditorApplication.update += UpdateCS; } } static void SaveScene() { if ( !System.IO.Directory.Exists( Application.dataPath + "/" + AutoSaveFolder ) ) { System.IO.Directory.CreateDirectory( Application.dataPath + "/" + AutoSaveFolder ); AssetDatabase.Refresh(); } var relativeSavePath = "Assets/" + AutoSaveFolder + "/"; EditorSceneManager.SaveScene( EditorSceneManager.GetActiveScene() , relativeSavePath + autoSaveFileName + ".unity" , true ); var dif = (float)EDITOR_TIMER - lastSave - m_saveInterval; if ( dif < m_saveInterval && dif > 0 ) lastSave = (float)EDITOR_TIMER - dif; else lastSave = (float)EDITOR_TIMER; if ( m_debug ) Debug.Log( "Auto-Save Current Scene: " + relativeSavePath + autoSaveFileName + ".unity" ); } //* UPDATER *// public class CachedBool { public CachedBool( string key , bool defaultValue ) { this.key = key; this.defaultValue = defaultValue ? 1 : 0; this.lastDif = -1; } string key; int lastDif; int defaultValue; bool CurrentDif { get { if ( lastDif == -1 ) lastDif = EditorPrefs.GetInt( key , defaultValue ); return lastDif == 1; } set { if ( lastDif == -1 ) lastDif = EditorPrefs.GetInt( key , defaultValue ); if ( lastDif == (value ? 1 : 0) ) return; lastDif = value ? 1 : 0; EditorPrefs.SetInt( key , value ? 1 : 0 ); } } public static implicit operator bool( CachedBool d ) { return d.CurrentDif; } internal void Set( bool i ) { CurrentDif = i; } } public class CachedFloat { public CachedFloat( string key , float defaultValue ) { this.key = key; this.defaultValue = defaultValue; this.lastDif = -1; } string key; float lastDif; float defaultValue; float CurrentDif { get { if ( lastDif == -1 ) lastDif = EditorPrefs.GetFloat( key , defaultValue ); return lastDif; } set { if ( lastDif == -1 ) lastDif = EditorPrefs.GetFloat( key , defaultValue ); if ( lastDif == value ) return; lastDif = value; EditorPrefs.SetFloat( key , value ); } } public static implicit operator float( CachedFloat d ) { return d.CurrentDif; } internal void Set( float i ) { CurrentDif = i; } } public class CachedInt { public CachedInt( string key , int defaultValue ) { this.key = key; this.defaultValue = defaultValue; this.lastDif = -1; } string key; int lastDif; int defaultValue; int CurrentDif { get { if ( lastDif == -1 ) lastDif = EditorPrefs.GetInt( key , defaultValue ); return lastDif; } set { if ( lastDif == -1 ) lastDif = EditorPrefs.GetInt( key , defaultValue ); if ( lastDif == value ) return; lastDif = value; EditorPrefs.SetInt( key , value ); } } public static implicit operator int( CachedInt d ) { return d.CurrentDif; } internal void Set( int i ) { CurrentDif = i; } } static string GET_STRING( string key ) { return EditorPrefs.GetString( "EModules/AutoSave/" + key ); } static void SET_STRING( string key , string value ) { EditorPrefs.SetString( "EModules/AutoSave/" + key , value ); } } } #endif //* private *// //* private *// //* editorprefs *// /*static float GET_FLOAT( string key ) { return EditorPrefs.GetFloat( "EModules/AutoSave/" + key ); } static void SET_FLOAT( string key , float value ) { EditorPrefs.SetFloat( "EModules/AutoSave/" + key , value ); } static string GET_STRING( string key ) { return EditorPrefs.GetString( "EModules/AutoSave/" + key ); } static void SET_STRING( string key , string value ) { EditorPrefs.SetString( "EModules/AutoSave/" + key , value ); } static int GET_INT( string key ) { return EditorPrefs.GetInt( "EModules/AutoSave/" + key ); } static void SET_INT( string key , int value ) { EditorPrefs.SetInt( "EModules/AutoSave/" + key , value ); } static bool GET_BOOL( string key ) { return EditorPrefs.GetBool( "EModules/AutoSave/" + key ); } static void SET_BOOL( string key , bool value ) { EditorPrefs.SetBool( "EModules/AutoSave/" + key , value ); } static bool HAS_KEY( string key ) { if ( EditorPrefs.HasKey( "EModules/AutoSave/" + key ) ) return true; return false; / * if (EditorPrefs.HasKey( "AutoSave/" + key )) return true; return EditorPrefs.HasKey( key );* / }*/ //* editorprefs *// //* props *// /* static float lastSave { get { return GET_FLOAT( "nextsave" ); } set { EditorPrefs.SetFloat( "nextsave" , value ); } }*/ /* class MyCustomSettingsProvider : SettingsProvider { private SerializedObject m_CustomSettings; public MyCustomSettingsProvider( string path , SettingsScope scope = SettingsScope.Project ) : base( path , scope ) { } public static bool IsSettingsAvailable() { return true; } public override void OnActivate( string searchContext , UnityEngine.UIElements.VisualElement rootElement ) { } public override void OnGUI( string searchContext ) { _OnPreferencesGUI( searchContext ); } // Register the SettingsProvider [SettingsProvider] public static SettingsProvider CreateMyCustomSettingsProvider() { if ( IsSettingsAvailable() ) { var provider = new MyCustomSettingsProvider("Project/Auto-Save", SettingsScope.Project); // Automatically extract all keywords from the Styles. provider.keywords = new HashSet( new[] { "AutoSave" , "Auto" , "Save" , "Auto-Save" } ); return provider; } // Settings Asset doesn't exist yet; no need to display anything in the Settings window. return null; } }*/ /* static class MyCustomSettingsIMGUIRegister { } [SettingsProvider] public static SettingsProvider CreateMyCustomSettingsProvider() { // First parameter is the path in the Settings window. // Second parameter is the scope of this setting: it only appears in the Project Settings window. var provider = new SettingsProvider("Preferences/Auto-Save", SettingsScope.Project) { // By default the last token of the path is used as display name if no label is provided. label = "Auto-Save", // Create the SettingsProvider and initialize its drawing (IMGUI) function in place: guiHandler = _OnPreferencesGUI, // Populate the search keywords to enable smart search filtering and label highlighting: keywords = new HashSet(new[] { "AutoSave", "Auto", "Save" , "Auto-Save" }) }; Debug.Log( "ASD" ); return provider; }*/