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 : SerializedScriptableObject { [Serializable] private class PostProcessPathData { public string originPath; public string postProcessPath; public Object asset; 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] [Searchable] private Dictionary _allPostProcessPathData = new(); #region API public string this[string originPath] => GetPostProcessedPath(originPath); public string GetPostProcessedPath(string originPath) { if (!_allPostProcessPathData.TryGetValue(originPath, out var data)) { DebugUtil.LogError($"找不到后处理后的路径,请重新执行后处理 path:{originPath}"); return originPath; } return data.postProcessPath; } #if UNITY_EDITOR public void AddPostProcessData(Object asset, string postProcessPath) { if (!EditorUtility.IsPersistent(asset)) { return; } EditorUtility.SetDirty(this); var originPath = AssetDatabase.GetAssetPath(asset); if (!_allPostProcessPathData.TryGetValue(originPath, out var data)) { data = new PostProcessPathData(); _allPostProcessPathData.Add(originPath, data); } data.originPath = originPath; data.postProcessPath = postProcessPath; data.asset = asset; data.hashCode = CalculateMD5Hash(originPath); } public bool ShouldPostProcess(string assetPath) { if (!_allPostProcessPathData.TryGetValue(assetPath, out var savedData)) return true; var newHashCode = CalculateMD5Hash(assetPath); return newHashCode != savedData.hashCode; } public bool ShouldPostProcess(Object asset) { var path = AssetDatabase.GetAssetPath(asset); return ShouldPostProcess(path); } #endif #endregion #if UNITY_EDITOR private string CalculateMD5Hash(string filePath) { if (!File.Exists(filePath)) { DebugUtil.LogError($"filePath is null!"); return null; } 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 #if UNITY_EDITOR [Button("重新计算Hash值(点击后可以防止后处理所有场景)")] public void ReCalculateHashCode() { EditorUtility.SetDirty(this); foreach (var kv in _allPostProcessPathData) { kv.Value.hashCode = CalculateMD5Hash(kv.Value.originPath); } AssetDatabase.SaveAssets(); } [Button("重置Hash值(点击后可以后处理所有场景)")] public void ReSetHashCode() { EditorUtility.SetDirty(this); foreach (var kv in _allPostProcessPathData) { kv.Value.hashCode = ""; } AssetDatabase.SaveAssets(); } #endif }