NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Scene/PostProcessData.cs

174 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using Cysharp.Threading.Tasks;
using Gameplay;
using PhxhSDK;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
using UnityEditor;
#endif
/// <summary>
/// 记录所有场景/prefab后处理的数据
/// </summary>
[CreateAssetMenu(menuName = "Object后处理数据")]
public class PostProcessData : ScriptableObject
{
[Serializable]
private class PostProcessPathData
{
public string originPath;
public string postProcessPath;
}
[Serializable]
private class ObjectHashData
{
public Object target;
public string hashCode;
}
private const string PATH = "Assets/Scenes/ObjectPostProcessData.asset";
private static PostProcessData _instance;
public static PostProcessData Instance
{
get
{
if (_instance == null)
{
_instance = AssetManager.Instance.LoadAsset<PostProcessData>(PATH);
}
return _instance;
}
}
[ReadOnly]
[SerializeField]
private List<PostProcessPathData> _allPostProcessPathData = new();
[ReadOnly]
[SerializeField]
private List<ObjectHashData> _allObjectHashCode = new();
private Dictionary<string, string> _postProcessPathDic = new();
private Dictionary<Object, string> _hashCodeDic = new();
private void Awake()
{
Refresh();
}
#region API
public string this[string originPath] => GetPostProcessedPath(originPath);
public string GetPostProcessedPath(string originPath)
{
if (!_postProcessPathDic.TryGetValue(originPath, out var result))
{
DebugUtil.Log($"找不到后处理后的路径,请重新执行后处理 path:{originPath}");
result = originPath;
}
return result;
}
#if UNITY_EDITOR
public void AddPostProcessData(Object asset, string postProcessPath)
{
if (!EditorUtility.IsPersistent(asset))
{
return;
}
EditorUtility.SetDirty(this);
var originPath = AssetDatabase.GetAssetPath(asset);
_postProcessPathDic[originPath] = postProcessPath;
var hashCode = CalculateMD5Hash(originPath);
_hashCodeDic[asset] = hashCode;
Save();
}
public bool ShouldPostProcess(string assetPath)
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
if (asset == null)
return false;
return ShouldPostProcess(asset);
}
public bool ShouldPostProcess(Object asset)
{
if (!_hashCodeDic.TryGetValue(asset, out var savedHash))
return true;
var path = AssetDatabase.GetAssetPath(asset);
var newHashCode = CalculateMD5Hash(path);
return newHashCode != savedHash;
}
#endif
#endregion
#if UNITY_EDITOR
private string CalculateMD5Hash(string filePath)
{
using (var md5 = MD5.Create())
{
var allText = File.ReadAllText(filePath);
allText = allText.Replace("\r\n", "\r");
byte[] hashBytes = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(allText));
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
}
}
#endif
private void Save()
{
_allPostProcessPathData.Clear();
foreach (var kv in _postProcessPathDic)
{
_allPostProcessPathData.Add(new()
{
originPath = kv.Key,
postProcessPath = kv.Value,
});
}
_allObjectHashCode.Clear();
foreach (var kv in _hashCodeDic)
{
_allObjectHashCode.Add(new()
{
target = kv.Key,
hashCode = kv.Value,
});
}
}
private void Refresh()
{
_postProcessPathDic.Clear();
foreach (var postProcessPathData in _allPostProcessPathData)
{
_postProcessPathDic[postProcessPathData.originPath] = postProcessPathData.postProcessPath;
}
_hashCodeDic.Clear();
foreach (var objectHashData in _allObjectHashCode)
{
_hashCodeDic[objectHashData.target] = objectHashData.hashCode;
}
}
}