Files
plugin-library/Assets/02.InformationSave/RunTime/Abstract/AbstractInformation.cs

284 lines
9.4 KiB
C#
Raw Normal View History

2025-03-26 09:34:52 +08:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
using System.Linq;
namespace Stary.Evo.InformationSave
{
public abstract class AbstractInformation<T> : CustomEditorBase where T : InformationBase, new()
{
[HideInInspector] public List<T> _list = new List<T>();
/// <summary>
/// 配置文件存储路径
/// </summary>
2025-03-27 16:56:33 +08:00
string path = "InformationSaveData/ScriptObjectSaveData";
2025-03-26 09:34:52 +08:00
public virtual void Add()
{
_list.Add(new T());
Save(_list.Count - 1);
}
public abstract void Save(int index);
public abstract void Switch(int index);
2025-04-30 16:15:11 +08:00
2025-03-26 09:34:52 +08:00
public virtual T GetTransform(string desc)
{
int index = _list.FindIndex(n => n.desc == desc);
if (index != -1)
{
return _list[index];
}
else
{
2025-04-10 11:57:13 +08:00
Debug.LogError($"UnityEvo:{typeof(T)}:不存在该信息:" + desc);
2025-03-26 09:34:52 +08:00
return default(T);
}
}
public virtual void Delete(int index)
{
_list.RemoveAt(index);
}
public virtual void Set(string desc)
{
int index = _list.FindIndex(n => n.desc == desc);
if (index != -1) Switch(index);
}
2025-03-27 16:56:33 +08:00
2025-03-26 09:34:52 +08:00
#region Editor
#if UNITY_EDITOR
//更新
public void UpdateInformation()
{
2025-04-30 16:15:11 +08:00
string guid = GetPrefabGUID(this.gameObject)+GetPrefabHierarchyPath(this.gameObject);
if (guid == "")
{
UnityEditor.EditorUtility.DisplayDialog("错误", "可能存在错误\n1、无法在prefab预览中修改数据\n2、新增加物体需先同步为prefab", "确定");
return;
}
2025-03-27 16:56:33 +08:00
ScriptObjectSave scriptObjectSaveData = Resources.Load<ScriptObjectSave>(path);
if (scriptObjectSaveData == null)
2025-03-26 09:34:52 +08:00
{
2025-04-10 11:57:13 +08:00
Debug.LogError("UnityEvo:ScriptObjectSaveData配置文件丢失");
2025-03-26 09:34:52 +08:00
return;
}
2025-04-30 16:15:11 +08:00
if (scriptObjectSaveData.dic.ContainsKey(guid))
2025-03-26 09:34:52 +08:00
{
_list.Clear();
2025-04-30 16:15:11 +08:00
_list = scriptObjectSaveData.dic[guid].OfType<T>().ToList();
2025-03-26 09:34:52 +08:00
}
else
{
2025-04-30 16:15:11 +08:00
Debug.LogError($"UnityEvo:ScriptObjectSaveData中未存储物体名为:{this.gameObject}\n guid为:{guid}的数据!!!");
2025-03-26 09:34:52 +08:00
}
}
//动态保存
public bool PlayingSave()
{
//文件保存
2025-04-30 16:15:11 +08:00
string guid = GetPrefabGUID(this.gameObject)+GetPrefabHierarchyPath(this.gameObject);
if (guid == "")
2025-03-26 09:34:52 +08:00
{
2025-04-30 16:15:11 +08:00
UnityEditor.EditorUtility.DisplayDialog("错误", "可能存在错误\n1、无法在prefab预览中修改数据\n2、新增加物体需先同步为prefab", "确定");
return false;
}
// 加载 ScriptObjectSaveData
ScriptObjectSave scriptObjectSaveData = Resources.Load<ScriptObjectSave>(path);
if (scriptObjectSaveData == null)
{
scriptObjectSaveData = CheckAndCreateFoldersAndAsset();
//Debug.Log("创建了ScriptObjectSaveData文件");
}
2025-03-27 16:56:33 +08:00
2025-04-30 16:15:11 +08:00
if (scriptObjectSaveData.dic == null)
{
Debug.LogError("UnityEvo:ScriptObjectSaveData的dic为空");
return false;
}
2025-03-27 16:56:33 +08:00
2025-04-30 16:15:11 +08:00
// 检查是否已经存在相同的键
if (scriptObjectSaveData.dic.ContainsKey(guid))
{
// 如果存在,选择是否替换原有的 List
if (UnityEditor.EditorUtility.DisplayDialog("提示",
$"数据集下已有相同名称的物体数据\n是否覆盖更新\n 物体名为:{this.gameObject}\n guid为:{guid}", "确定",
"取消"))
2025-03-27 16:56:33 +08:00
{
2025-04-30 16:15:11 +08:00
scriptObjectSaveData.dic[guid] = new List<InformationBase>(_list);
2025-03-26 09:34:52 +08:00
}
else
{
2025-04-30 16:15:11 +08:00
return false;
2025-03-26 09:34:52 +08:00
}
}
2025-04-30 16:15:11 +08:00
else
{
// 如果不存在,添加新的键值对
scriptObjectSaveData.dic.Add(guid, new List<InformationBase>(_list));
}
AssetDatabase.SaveAssets();
EditorUtility.SetDirty(scriptObjectSaveData);
AssetDatabase.Refresh();
2025-03-26 09:34:52 +08:00
2025-04-30 16:15:11 +08:00
return true;
2025-03-26 09:34:52 +08:00
}
2025-03-27 16:56:33 +08:00
private ScriptObjectSave CheckAndCreateFoldersAndAsset()
{
string ResourcesFolderName = "Resources";
string InformationSaveDataFolderName = "InformationSaveData";
string ScriptObjectSaveDataFileName = "ScriptObjectSaveData";
ScriptObjectSave scriptableObject;
// 判断是否创建Resources文件夹
string resourcesPath = Path.Combine(Application.dataPath, ResourcesFolderName);
if (!Directory.Exists(resourcesPath))
{
Directory.CreateDirectory(resourcesPath);
}
// 判断是否创建InformationSaveData文件夹
string informationSaveDataPath = Path.Combine(resourcesPath, InformationSaveDataFolderName);
if (!Directory.Exists(informationSaveDataPath))
{
Directory.CreateDirectory(informationSaveDataPath);
}
2025-03-26 09:34:52 +08:00
2025-03-27 16:56:33 +08:00
// 创建ScriptObjectSaveData.asset文件
scriptableObject = ScriptableObject.CreateInstance<ScriptObjectSave>();
2025-04-30 16:15:11 +08:00
AssetDatabase.CreateAsset(scriptableObject,
"Assets/" + ResourcesFolderName + "/" + InformationSaveDataFolderName + "/" +
ScriptObjectSaveDataFileName + ".asset");
2025-03-27 16:56:33 +08:00
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
2025-04-30 16:15:11 +08:00
Debug.Log("UnityEvo:创建了: " + "Assets/" + ResourcesFolderName + "/" + InformationSaveDataFolderName + "/" +
ScriptObjectSaveDataFileName + ".asset 资产");
2025-03-27 16:56:33 +08:00
return scriptableObject;
}
2025-03-26 09:34:52 +08:00
//绘制
public override void Draw()
{
int length = _list.Count;
int deleteIndex = -1;
for (int i = 0; i < length; i++)
{
GUILayout.BeginHorizontal();
_list[i].desc = UnityEditor.EditorGUILayout.TextField(_list[i].desc);
if (GUILayout.Button("切换")) Switch(i);
if (GUILayout.Button("保存"))
{
Save(i);
2025-04-10 11:57:13 +08:00
if (PlayingSave()) Debug.Log("UnityEvo:保存成功!");
2025-03-26 09:34:52 +08:00
}
if (GUILayout.Button("上移") && i > 0)
{
T temp = _list[i - 1];
_list[i - 1] = _list[i];
_list[i] = temp;
}
if (GUILayout.Button("下移") && i < _list.Count - 1)
{
T temp = _list[i + 1];
_list[i + 1] = _list[i];
_list[i] = temp;
}
if (GUILayout.Button("删除") && UnityEditor.EditorUtility.DisplayDialog("警告", "你确定要删除吗?", "确定", "取消"))
deleteIndex = i;
GUILayout.EndHorizontal();
if (i != length - 1) GUILayout.Space(20);
}
if (deleteIndex != -1) Delete(deleteIndex);
GUILayout.Space(30);
GUILayout.BeginHorizontal();
if (GUILayout.Button("添加"))
{
Add();
}
if (GUILayout.Button("更新") && UnityEditor.EditorUtility.DisplayDialog("提示", "你确定要更新吗?", "确定", "取消"))
{
UpdateInformation();
GUILayout.BeginHorizontal();
}
GUILayout.EndHorizontal();
}
2025-04-30 16:15:11 +08:00
private string GetCurrentGUID()
{
string assetPath = AssetDatabase.GetAssetPath(this);
if (!string.IsNullOrEmpty(assetPath))
{
return AssetDatabase.AssetPathToGUID(assetPath);
}
return string.Empty;
}
private string GetPrefabGUID(GameObject obj)
{
string assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(obj);
Debug.Log("UnityEvo:GetPrefabHierarchyPath:" + GetPrefabHierarchyPath(obj));
if (!string.IsNullOrEmpty(assetPath))
{
return AssetDatabase.AssetPathToGUID(assetPath);
}
return string.Empty;
}
private string GetPrefabHierarchyPath(GameObject obj)
{
var path = new System.Text.StringBuilder();
var current = obj.transform;
//检测该预制体是否是实例
var root = PrefabUtility.GetNearestPrefabInstanceRoot(obj);
if (root != null)
{
while (current != null && current != root.transform)
{
path.Insert(0, current.name);
path.Insert(0, "/");
current = current.parent;
}
return path.ToString();
}
return string.Empty;
}
2025-03-26 09:34:52 +08:00
#else
public override void Draw(){}
#endif
}
#endregion
2025-04-30 16:15:11 +08:00
2025-03-26 09:34:52 +08:00
[System.Serializable]
public class InformationBase
{
public string desc = "初始";
}
}