|
|
|
|
#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<string>( 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<string>(new[] { "AutoSave", "Auto", "Save" , "Auto-Save" })
|
|
|
|
|
};
|
|
|
|
|
Debug.Log( "ASD" );
|
|
|
|
|
return provider;
|
|
|
|
|
}*/
|