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

284 lines
9.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
string path = "InformationSaveData/ScriptObjectSaveData";
public virtual void Add()
{
_list.Add(new T());
Save(_list.Count - 1);
}
public abstract void Save(int index);
public abstract void Switch(int index);
public virtual T GetTransform(string desc)
{
int index = _list.FindIndex(n => n.desc == desc);
if (index != -1)
{
return _list[index];
}
else
{
Debug.LogError($"UnityEvo:{typeof(T)}:不存在该信息:" + desc);
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);
}
#region Editor
#if UNITY_EDITOR
//更新
public void UpdateInformation()
{
string guid = GetPrefabGUID(this.gameObject)+GetPrefabHierarchyPath(this.gameObject);
if (guid == "")
{
UnityEditor.EditorUtility.DisplayDialog("错误", "可能存在错误\n1、无法在prefab预览中修改数据\n2、新增加物体需先同步为prefab", "确定");
return;
}
ScriptObjectSave scriptObjectSaveData = Resources.Load<ScriptObjectSave>(path);
if (scriptObjectSaveData == null)
{
Debug.LogError("UnityEvo:ScriptObjectSaveData配置文件丢失");
return;
}
if (scriptObjectSaveData.dic.ContainsKey(guid))
{
_list.Clear();
_list = scriptObjectSaveData.dic[guid].OfType<T>().ToList();
}
else
{
Debug.LogError($"UnityEvo:ScriptObjectSaveData中未存储物体名为:{this.gameObject}\n guid为:{guid}的数据!!!");
}
}
//动态保存
public bool PlayingSave()
{
//文件保存
string guid = GetPrefabGUID(this.gameObject)+GetPrefabHierarchyPath(this.gameObject);
if (guid == "")
{
UnityEditor.EditorUtility.DisplayDialog("错误", "可能存在错误\n1、无法在prefab预览中修改数据\n2、新增加物体需先同步为prefab", "确定");
return false;
}
// 加载 ScriptObjectSaveData
ScriptObjectSave scriptObjectSaveData = Resources.Load<ScriptObjectSave>(path);
if (scriptObjectSaveData == null)
{
scriptObjectSaveData = CheckAndCreateFoldersAndAsset();
//Debug.Log("创建了ScriptObjectSaveData文件");
}
if (scriptObjectSaveData.dic == null)
{
Debug.LogError("UnityEvo:ScriptObjectSaveData的dic为空");
return false;
}
// 检查是否已经存在相同的键
if (scriptObjectSaveData.dic.ContainsKey(guid))
{
// 如果存在,选择是否替换原有的 List
if (UnityEditor.EditorUtility.DisplayDialog("提示",
$"数据集下已有相同名称的物体数据\n是否覆盖更新\n 物体名为:{this.gameObject}\n guid为:{guid}", "确定",
"取消"))
{
scriptObjectSaveData.dic[guid] = new List<InformationBase>(_list);
}
else
{
return false;
}
}
else
{
// 如果不存在,添加新的键值对
scriptObjectSaveData.dic.Add(guid, new List<InformationBase>(_list));
}
AssetDatabase.SaveAssets();
EditorUtility.SetDirty(scriptObjectSaveData);
AssetDatabase.Refresh();
return true;
}
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);
}
// 创建ScriptObjectSaveData.asset文件
scriptableObject = ScriptableObject.CreateInstance<ScriptObjectSave>();
AssetDatabase.CreateAsset(scriptableObject,
"Assets/" + ResourcesFolderName + "/" + InformationSaveDataFolderName + "/" +
ScriptObjectSaveDataFileName + ".asset");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("UnityEvo:创建了: " + "Assets/" + ResourcesFolderName + "/" + InformationSaveDataFolderName + "/" +
ScriptObjectSaveDataFileName + ".asset 资产");
return scriptableObject;
}
//绘制
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);
if (PlayingSave()) Debug.Log("UnityEvo:保存成功!");
}
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();
}
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;
}
#else
public override void Draw(){}
#endif
}
#endregion
[System.Serializable]
public class InformationBase
{
public string desc = "初始";
}
}