2025-02-08 23:09:50 -05:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-03-01 12:50:13 -05:00
|
|
|
|
using System.Globalization;
|
2025-03-01 21:26:16 -05:00
|
|
|
|
using System.IO;
|
2025-02-19 09:15:51 -05:00
|
|
|
|
using Ichni.Editor;
|
2025-02-08 23:09:50 -05:00
|
|
|
|
using Ichni.RhythmGame;
|
|
|
|
|
|
using Ichni.RhythmGame.Beatmap;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Ichni
|
|
|
|
|
|
{
|
|
|
|
|
|
public class ProjectManager
|
|
|
|
|
|
{
|
|
|
|
|
|
public static readonly ES3Settings SaveSettings = new ES3Settings
|
|
|
|
|
|
{
|
|
|
|
|
|
compressionType = ES3.CompressionType.None,
|
|
|
|
|
|
encryptionType = ES3.EncryptionType.None,
|
|
|
|
|
|
format = ES3.Format.JSON,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly ES3Settings ExportSettings = new ES3Settings
|
|
|
|
|
|
{
|
|
|
|
|
|
compressionType = ES3.CompressionType.Gzip,
|
|
|
|
|
|
encryptionType = ES3.EncryptionType.AES,
|
|
|
|
|
|
encryptionPassword = "Soullies515",
|
|
|
|
|
|
format = ES3.Format.JSON,
|
|
|
|
|
|
};
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
public SaveManager saveManager;
|
|
|
|
|
|
public LoadManager loadManager;
|
|
|
|
|
|
public ExportManager exportManager;
|
2025-03-01 12:50:13 -05:00
|
|
|
|
public BeatmapClipManager beatmapClipManager;
|
2025-03-24 13:41:50 -04:00
|
|
|
|
public NotePrefabManager notePrefabManager;
|
2025-03-01 21:26:16 -05:00
|
|
|
|
public AutoSaveManager autoSaveManager;
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
public ProjectManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
saveManager = new SaveManager();
|
|
|
|
|
|
loadManager = new LoadManager();
|
|
|
|
|
|
exportManager = new ExportManager();
|
2025-03-01 12:50:13 -05:00
|
|
|
|
beatmapClipManager = new BeatmapClipManager();
|
2025-03-24 13:41:50 -04:00
|
|
|
|
notePrefabManager = new NotePrefabManager();
|
2025-03-01 21:26:16 -05:00
|
|
|
|
autoSaveManager = new AutoSaveManager();
|
2025-02-08 23:09:50 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-08 14:21:10 -05:00
|
|
|
|
public void GenerateEmptyProject(ProjectInformation_BM projectInfo_BM, SongInformation_BM songInfo_BM)
|
2025-02-08 23:09:50 -05:00
|
|
|
|
{
|
2025-03-08 14:21:10 -05:00
|
|
|
|
projectInfo_BM.ExecuteBM();
|
|
|
|
|
|
songInfo_BM.ExecuteBM();
|
|
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
EditorManager.instance.beatmapContainer = new BeatmapContainer();
|
|
|
|
|
|
EditorManager.instance.commandScripts = new CommandScripts(new List<string>());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class ExportManager
|
|
|
|
|
|
{
|
|
|
|
|
|
public void Export()
|
|
|
|
|
|
{
|
|
|
|
|
|
string exportPath = Application.streamingAssetsPath + "/Export/" +
|
|
|
|
|
|
EditorManager.instance.projectInformation.projectName;
|
|
|
|
|
|
string projectInfoPath = exportPath + "/ProjectInfo.bytes";
|
|
|
|
|
|
string songInfoPath = exportPath + "/SongInfo.bytes";
|
|
|
|
|
|
string beatmapPath = exportPath + "/BeatMap.bytes";
|
|
|
|
|
|
string commandScriptsPath = exportPath + "/CommandScripts.bytes";
|
|
|
|
|
|
|
2025-02-19 09:15:51 -05:00
|
|
|
|
LogWindow.Log("Start Exporting...");
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
ExportProjectInfo(projectInfoPath);
|
|
|
|
|
|
ExportSongInfo(songInfoPath);
|
|
|
|
|
|
ExportBeatMap(beatmapPath);
|
|
|
|
|
|
ExportCommandScripts(commandScriptsPath);
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-19 09:15:51 -05:00
|
|
|
|
LogWindow.Log("Export Complete", Color.green);
|
2025-02-08 23:09:50 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ExportProjectInfo(string exportPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.projectInformation.SaveBM();
|
|
|
|
|
|
ES3.Save("ProjectInformation", EditorManager.instance.projectInformation.matchedBM as ProjectInformation_BM,
|
|
|
|
|
|
exportPath, ProjectManager.ExportSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ExportSongInfo(string exportPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.songInformation.SaveBM();
|
|
|
|
|
|
ES3.Save("SongInformation", EditorManager.instance.songInformation.matchedBM as SongInformation_BM,
|
|
|
|
|
|
exportPath, ProjectManager.ExportSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ExportBeatMap(string exportPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.beatmapContainer.SaveBM();
|
|
|
|
|
|
ES3.Save("BeatMap", EditorManager.instance.beatmapContainer.matchedBM as BeatmapContainer_BM,
|
|
|
|
|
|
exportPath, ProjectManager.ExportSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ExportCommandScripts(string exportPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.commandScripts.SaveBM();
|
|
|
|
|
|
ES3.Save("CommandScripts", EditorManager.instance.commandScripts.matchedBM as CommandScripts_BM,
|
|
|
|
|
|
exportPath, ProjectManager.ExportSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class SaveManager
|
|
|
|
|
|
{
|
|
|
|
|
|
public void Save()
|
|
|
|
|
|
{
|
2025-02-19 09:15:51 -05:00
|
|
|
|
LogWindow.Log("Start Saving...");
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
SaveProjectInfo();
|
|
|
|
|
|
SaveSongInfo();
|
|
|
|
|
|
SaveBeatMap();
|
|
|
|
|
|
SaveCommandScripts();
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-19 09:15:51 -05:00
|
|
|
|
LogWindow.Log("Save Complete", Color.green);
|
2025-02-08 23:09:50 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveProjectInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.projectInformation.SaveBM();
|
|
|
|
|
|
ES3.Save("ProjectInformation", EditorManager.instance.projectInformation.matchedBM as ProjectInformation_BM,
|
|
|
|
|
|
EditorManager.instance.projectInformation.peojectInfoPath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveSongInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.songInformation.SaveBM();
|
|
|
|
|
|
ES3.Save("SongInformation", EditorManager.instance.songInformation.matchedBM as SongInformation_BM,
|
|
|
|
|
|
EditorManager.instance.projectInformation.songInfoPath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveBeatMap()
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.beatmapContainer.SaveBM();
|
|
|
|
|
|
ES3.Save("BeatMap", EditorManager.instance.beatmapContainer.matchedBM as BeatmapContainer_BM,
|
|
|
|
|
|
EditorManager.instance.projectInformation.beatmapPath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveCommandScripts()
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.commandScripts.SaveBM();
|
|
|
|
|
|
ES3.Save("CommandScripts", EditorManager.instance.commandScripts.matchedBM as CommandScripts_BM,
|
|
|
|
|
|
EditorManager.instance.projectInformation.CommandScriptsPath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class LoadManager
|
|
|
|
|
|
{
|
2025-03-08 14:21:10 -05:00
|
|
|
|
public void Load(string projectName)
|
2025-02-08 23:09:50 -05:00
|
|
|
|
{
|
|
|
|
|
|
LoadProjectInfo(projectName);
|
|
|
|
|
|
LoadSongInfo();
|
|
|
|
|
|
LoadCommandScripts();
|
2025-02-28 20:08:00 +08:00
|
|
|
|
LoadBeatMap();
|
2025-02-19 09:15:51 -05:00
|
|
|
|
LogWindow.Log("Load Complete", Color.green);
|
2025-02-08 23:09:50 -05:00
|
|
|
|
}
|
2025-02-28 20:08:00 +08:00
|
|
|
|
|
2025-02-08 23:09:50 -05:00
|
|
|
|
private void LoadProjectInfo(string projectName)
|
|
|
|
|
|
{
|
|
|
|
|
|
string projectInfoPath = Application.streamingAssetsPath + "/Projects/" + projectName + "/ProjectInfo.json";
|
|
|
|
|
|
ES3.Load<ProjectInformation_BM>("ProjectInformation", projectInfoPath, ProjectManager.SaveSettings).ExecuteBM();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void LoadSongInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
ES3.Load<SongInformation_BM>("SongInformation", EditorManager.instance.projectInformation.songInfoPath,
|
|
|
|
|
|
ProjectManager.SaveSettings).ExecuteBM();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void LoadBeatMap()
|
|
|
|
|
|
{
|
|
|
|
|
|
ES3.Load<BeatmapContainer_BM>("BeatMap", EditorManager.instance.projectInformation.beatmapPath,
|
|
|
|
|
|
ProjectManager.SaveSettings).ExecuteBM();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void LoadCommandScripts()
|
|
|
|
|
|
{
|
|
|
|
|
|
ES3.Load<CommandScripts_BM>("CommandScripts", EditorManager.instance.projectInformation.CommandScriptsPath,
|
|
|
|
|
|
ProjectManager.SaveSettings).ExecuteBM();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
|
|
|
|
|
public class BeatmapClipManager
|
|
|
|
|
|
{
|
2025-03-02 02:18:28 -05:00
|
|
|
|
public void SaveClip(string clipName)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Start Saving Clip...");
|
|
|
|
|
|
|
2025-04-02 18:18:25 -04:00
|
|
|
|
if (EditorManager.instance.operationManager.currentSelectedElements.Count != 1) // TODO: 后续适应多选
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Please select only one Game Element to save the beatmap clip.", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GameElement selectedElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
if (selectedElement is null)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
2025-03-02 02:18:28 -05:00
|
|
|
|
LogWindow.Log("Please select a Game Element to save the beatmap clip.", Color.red);
|
2025-03-01 12:50:13 -05:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
_SaveClip(selectedElement, clipName);
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
|
|
|
|
|
LogWindow.Log("Save Clip Complete", Color.green);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
public void LoadClip(string clipName)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Start Loading Clip...");
|
|
|
|
|
|
|
|
|
|
|
|
if(!ES3.FileExists(Application.streamingAssetsPath + "/Clips/" + clipName + ".json"))
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Clip not found", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-04-02 18:18:25 -04:00
|
|
|
|
|
|
|
|
|
|
if (EditorManager.instance.operationManager.currentSelectedElements.Count != 1) // TODO: 后续适应多选
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Please select only one Game Element to load the beatmap clip.", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
2025-04-02 18:18:25 -04:00
|
|
|
|
GameElement selectedElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
2025-03-02 02:18:28 -05:00
|
|
|
|
|
|
|
|
|
|
if (selectedElement is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Please select a Game Element to load the beatmap clip.", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
Debug.Log(selectedElement.elementName + " " + selectedElement.elementGuid);
|
|
|
|
|
|
|
|
|
|
|
|
_LoadClip(selectedElement, clipName);
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
|
|
|
|
|
LogWindow.Log("Load Clip Complete", Color.green);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
private void _SaveClip(GameElement element, string clipName)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
|
|
|
|
|
List<BaseElement_BM> clip = new List<BaseElement_BM>();
|
|
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
element.GetAllGameElementsFromThis().ForEach(e =>
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
|
|
|
|
|
e.SaveBM();
|
|
|
|
|
|
clip.Add(e.matchedBM);
|
|
|
|
|
|
e.submoduleList.ForEach(s =>
|
|
|
|
|
|
{
|
|
|
|
|
|
s.SaveBM();
|
|
|
|
|
|
clip.Add(s.matchedBM);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json";
|
|
|
|
|
|
ES3.Save("Clip", clip, filePath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
private void _LoadClip(GameElement target, string clipName)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
|
|
|
|
|
string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json";
|
|
|
|
|
|
List<BaseElement_BM> clip = ES3.Load<List<BaseElement_BM>>("Clip", filePath, ProjectManager.SaveSettings);
|
2025-03-02 02:18:28 -05:00
|
|
|
|
|
|
|
|
|
|
//对于第一个元素,需要特殊处理,将它放入目标物体的子物体列表中
|
|
|
|
|
|
GameElement_BM first = clip[0] as GameElement_BM;
|
2025-03-24 13:41:50 -04:00
|
|
|
|
List<BaseElement_BM> firstAttaches = GameElement_BM.GetAllAttachedBaseElements(first, clip);
|
2025-03-02 02:18:28 -05:00
|
|
|
|
first.elementGuid = Guid.NewGuid();
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(first.elementGuid, first);
|
|
|
|
|
|
firstAttaches.ForEach(e => { e.attachedElementGuid = first.elementGuid; });
|
|
|
|
|
|
|
|
|
|
|
|
//将目标物体(临时)存入读存档的Dictionary中
|
|
|
|
|
|
target.SaveBM();
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(target.elementGuid, target.matchedBM as GameElement_BM);
|
|
|
|
|
|
(target.matchedBM as GameElement_BM).matchedElement = target;
|
|
|
|
|
|
first.attachedElementGuid = target.elementGuid;
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
for (var index = 1; index < clip.Count; index++)
|
2025-03-01 12:50:13 -05:00
|
|
|
|
{
|
2025-03-02 02:18:28 -05:00
|
|
|
|
var element = clip[index];
|
2025-03-01 12:50:13 -05:00
|
|
|
|
if (element is GameElement_BM gameElement)
|
|
|
|
|
|
{
|
2025-03-24 13:41:50 -04:00
|
|
|
|
List<BaseElement_BM> attachedElements = GameElement_BM.GetAllAttachedBaseElements(gameElement, clip);
|
2025-03-01 12:50:13 -05:00
|
|
|
|
gameElement.elementGuid = Guid.NewGuid();
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(gameElement.elementGuid, gameElement);
|
|
|
|
|
|
attachedElements.ForEach(e => { e.attachedElementGuid = gameElement.elementGuid; });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-02 02:18:28 -05:00
|
|
|
|
|
|
|
|
|
|
first.ExecuteBM();
|
2025-03-01 12:50:13 -05:00
|
|
|
|
|
2025-03-02 02:18:28 -05:00
|
|
|
|
for (var index = 1; index < clip.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
clip[index].ExecuteBM();
|
|
|
|
|
|
}
|
2025-03-01 12:50:13 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-01 21:26:16 -05:00
|
|
|
|
|
2025-03-24 13:41:50 -04:00
|
|
|
|
public class NotePrefabManager
|
|
|
|
|
|
{
|
|
|
|
|
|
private string notePrefabPath => Application.streamingAssetsPath + "/NotePrefabs";
|
|
|
|
|
|
private string GetNotePrefabPath(string notePrefabName) => notePrefabPath + "/" + notePrefabName + ".json";
|
|
|
|
|
|
|
|
|
|
|
|
public void SaveNotePrefab(NoteBase note, string noteName)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<BaseElement_BM> clip = new List<BaseElement_BM>();
|
|
|
|
|
|
|
|
|
|
|
|
note.GetAllGameElementsFromThis().ForEach(e =>
|
|
|
|
|
|
{
|
|
|
|
|
|
e.SaveBM();
|
|
|
|
|
|
clip.Add(e.matchedBM);
|
|
|
|
|
|
e.submoduleList.ForEach(s =>
|
|
|
|
|
|
{
|
|
|
|
|
|
s.SaveBM();
|
|
|
|
|
|
clip.Add(s.matchedBM);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
ES3.Save("Note", clip, GetNotePrefabPath(noteName), ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void LoadNotePrefab(NoteBase target, string noteName)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<BaseElement_BM> clip = ES3.Load<List<BaseElement_BM>>("Note", GetNotePrefabPath(noteName), ProjectManager.SaveSettings);
|
|
|
|
|
|
|
|
|
|
|
|
if (clip == null || clip.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Note prefab not found", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
target.SaveBM();
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(target.elementGuid, target.matchedBM as GameElement_BM);
|
|
|
|
|
|
(target.matchedBM as GameElement_BM).matchedElement = target;
|
|
|
|
|
|
|
|
|
|
|
|
GameElement_BM first = clip[0] as GameElement_BM;
|
|
|
|
|
|
List<BaseElement_BM> firstAttaches = GameElement_BM.GetAllAttachedBaseElements(first, clip);
|
|
|
|
|
|
first.elementGuid = target.elementGuid;
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(first.elementGuid, first);
|
|
|
|
|
|
firstAttaches.ForEach(e => { e.attachedElementGuid = first.elementGuid; });
|
|
|
|
|
|
|
|
|
|
|
|
for (var index = 1; index < clip.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var element = clip[index];
|
|
|
|
|
|
if (element is GameElement_BM gameElement)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<BaseElement_BM> attachedElements = GameElement_BM.GetAllAttachedBaseElements(gameElement, clip);
|
|
|
|
|
|
gameElement.elementGuid = Guid.NewGuid();
|
|
|
|
|
|
GameElement_BM.identifier.TryAdd(gameElement.elementGuid, gameElement);
|
|
|
|
|
|
attachedElements.ForEach(e => { e.attachedElementGuid = gameElement.elementGuid; });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (var index = 1; index < clip.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
clip[index].ExecuteBM();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-01 21:26:16 -05:00
|
|
|
|
public class AutoSaveManager
|
|
|
|
|
|
{
|
|
|
|
|
|
private string autoSavePath => Application.streamingAssetsPath + "/AutoSave/" +
|
|
|
|
|
|
EditorManager.instance.projectInformation.projectName;
|
|
|
|
|
|
private string GetAutoSavePath(string autoSaveName) => autoSavePath + "/" + autoSaveName + ".json";
|
|
|
|
|
|
private float autoSaveInterval => EditorManager.instance.editorSettings.autoSaveInterval;
|
|
|
|
|
|
private int maximumAutoSaveCount => EditorManager.instance.editorSettings.maximumAutoSaveCount;
|
|
|
|
|
|
|
|
|
|
|
|
public float autoSaveTimer;
|
|
|
|
|
|
|
|
|
|
|
|
public AutoSaveManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
autoSaveTimer = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateAutoSave()
|
|
|
|
|
|
{
|
|
|
|
|
|
autoSaveTimer += Time.deltaTime;
|
|
|
|
|
|
if (autoSaveTimer >= autoSaveInterval)
|
|
|
|
|
|
{
|
|
|
|
|
|
AutoSave();
|
|
|
|
|
|
autoSaveTimer = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void AutoSave()
|
|
|
|
|
|
{
|
|
|
|
|
|
List<string> saveFiles = GetSortedSaveFiles();
|
|
|
|
|
|
|
|
|
|
|
|
if (saveFiles.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 删除最旧的存档(如果超过数量)
|
|
|
|
|
|
if (saveFiles.Count >= maximumAutoSaveCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
string oldestSave = saveFiles[saveFiles.Count - 1];
|
|
|
|
|
|
File.Delete(oldestSave);
|
|
|
|
|
|
saveFiles.RemoveAt(saveFiles.Count - 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 依次重命名存档
|
|
|
|
|
|
for (int i = saveFiles.Count - 1; i >= 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
string oldPath = saveFiles[i];
|
|
|
|
|
|
string newPath = GetAutoSavePath($"AutoSave_{i + 1}");
|
|
|
|
|
|
File.Move(oldPath, newPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存最新存档
|
|
|
|
|
|
string newestSavePath = GetAutoSavePath("AutoSave_0");
|
|
|
|
|
|
SaveBeatMap(newestSavePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SaveBeatMap(string autoSavePath)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorManager.instance.beatmapContainer.SaveBM();
|
|
|
|
|
|
ES3.Save("BeatMap", EditorManager.instance.beatmapContainer.matchedBM as BeatmapContainer_BM,
|
|
|
|
|
|
autoSavePath, ProjectManager.SaveSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<string> GetSortedSaveFiles()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!ES3.DirectoryExists(autoSavePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(autoSavePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<string> saveFiles = new List<string>(Directory.GetFiles(autoSavePath, "AutoSave_*.es3"));
|
|
|
|
|
|
saveFiles.Sort(string.Compare);
|
|
|
|
|
|
return saveFiles;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-08 23:09:50 -05:00
|
|
|
|
}
|