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 /// /// 记录所有场景/prefab后处理的数据 /// [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(PATH); } return _instance; } } [ReadOnly] [SerializeField] private List _allPostProcessPathData = new(); [ReadOnly] [SerializeField] private List _allObjectHashCode = new(); private Dictionary _postProcessPathDic = new(); private Dictionary _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(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; } } }