174 lines
4.3 KiB
C#
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|