Pārlūkot izejas kodu

动画系统支持手改

SZAND\msx_2 7 mēneši atpakaļ
vecāks
revīzija
ee9b63b329
1 mainītis faili ar 87 papildinājumiem un 105 dzēšanām
  1. 87 105
      ActionTowerDefense/Assets/Editor/SkeletonDataReader.cs

+ 87 - 105
ActionTowerDefense/Assets/Editor/SkeletonDataReader.cs

@@ -3,16 +3,15 @@ using Spine.Unity;
 using System.Collections.Generic;
 using UnityEditor;
 using System.Linq;
-using System;
 using System.IO;
+using System;
 using Spine;
 
 [InitializeOnLoad]
 public class SkeletonDataMonitor
 {
     private static Dictionary<string, CachedPrefabData> _prefabCache = new Dictionary<string, CachedPrefabData>();
-    private static DateTime _lastCheckTime;
-    private const double MIN_CHECK_INTERVAL = 2.0;
+    private static Dictionary<SkeletonDataAsset, List<string>> _skeletonToPrefabs = new Dictionary<SkeletonDataAsset, List<string>>();
 
     private struct CachedPrefabData
     {
@@ -22,138 +21,106 @@ public class SkeletonDataMonitor
 
     static SkeletonDataMonitor()
     {
+        // 只监听必要的事件
         EditorApplication.hierarchyChanged += OnHierarchyChanged;
-        EditorApplication.update += OnEditorUpdate;
         Selection.selectionChanged += OnSelectionChanged;
-        AssemblyReloadEvents.afterAssemblyReload += RefreshCache;
-
-        // 新版Unity的Undo回调注册方式
-        Undo.undoRedoPerformed += OnUndoRedo;
+        AssemblyReloadEvents.afterAssemblyReload += InitializeCache;
 
-        RefreshCache();
+        InitializeCache();
     }
 
-    private static void OnUndoRedo()
+    private static void InitializeCache()
     {
-        RefreshCache();
-    }
+        _prefabCache.Clear();
+        _skeletonToPrefabs.Clear();
 
-    private static void OnHierarchyChanged()
-    {
-        if ((DateTime.Now - _lastCheckTime).TotalSeconds < MIN_CHECK_INTERVAL)
-            return;
+        var allPrefabs = AssetDatabase.FindAssets("t:Prefab")
+            .Select(AssetDatabase.GUIDToAssetPath)
+            .Where(p => p.EndsWith(".prefab"));
 
-        EditorApplication.delayCall += () =>
+        foreach (var path in allPrefabs)
         {
-            ProcessActiveSceneObjects();
-            _lastCheckTime = DateTime.Now;
-        };
-    }
-
-    private static void OnEditorUpdate()
-    {
-        if ((DateTime.Now - _lastCheckTime).TotalSeconds < MIN_CHECK_INTERVAL)
-            return;
-
-        ProcessActiveSceneObjects();
-        _lastCheckTime = DateTime.Now;
-    }
-
-    private static void OnSelectionChanged()
-    {
-        ProcessSelectedObjects();
+            var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+            var skeleton = prefab.GetComponentInChildren<SkeletonRenderer>();
+            if (skeleton != null && skeleton.skeletonDataAsset != null)
+            {
+                CachePrefab(path, skeleton.skeletonDataAsset);
+            }
+        }
     }
 
-    private static void ProcessActiveSceneObjects()
+    private static void CachePrefab(string path, SkeletonDataAsset skeletonData)
     {
-        var skeletons = GameObject.FindObjectsOfType<SkeletonRenderer>(true);
-        foreach (var skeleton in skeletons)
+        _prefabCache[path] = new CachedPrefabData
         {
-            ProcessSkeletonChange(skeleton);
-        }
-    }
+            skeletonDataAsset = skeletonData,
+            lastModified = File.GetLastWriteTime(path)
+        };
 
-    private static void ProcessSelectedObjects()
-    {
-        foreach (var obj in Selection.objects.OfType<GameObject>())
+        if (!_skeletonToPrefabs.ContainsKey(skeletonData))
         {
-            var skeleton = obj.GetComponentInChildren<SkeletonRenderer>();
-            if (skeleton != null)
-            {
-                ProcessSkeletonChange(skeleton);
-            }
+            _skeletonToPrefabs[skeletonData] = new List<string>();
         }
-    }
-
-    private static void ProcessSkeletonChange(SkeletonRenderer skeleton)
-    {
-        var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(skeleton.gameObject);
-        if (!string.IsNullOrEmpty(prefabPath))
+        if (!_skeletonToPrefabs[skeletonData].Contains(path))
         {
-            CheckAndProcessPrefab(prefabPath, skeleton.skeletonDataAsset);
+            _skeletonToPrefabs[skeletonData].Add(path);
         }
     }
 
-    private static void CheckAndProcessPrefab(string prefabPath, SkeletonDataAsset skeletonData)
+    private static void OnHierarchyChanged()
     {
-        if (!_prefabCache.TryGetValue(prefabPath, out var cache) ||
-            cache.skeletonDataAsset != skeletonData ||
-            cache.lastModified != File.GetLastWriteTime(prefabPath))
+        // 只检查新添加的对象
+        var newSkeletons = GameObject.FindObjectsOfType<SkeletonRenderer>(true)
+            .Where(s => PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(s.gameObject) != null);
+
+        foreach (var skeleton in newSkeletons)
         {
-            WriteData(prefabPath);
-            _prefabCache[prefabPath] = new CachedPrefabData
+            if (skeleton.skeletonDataAsset != null)
             {
-                skeletonDataAsset = skeletonData,
-                lastModified = File.GetLastWriteTime(prefabPath)
-            };
+                var path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(skeleton.gameObject);
+                if (!_prefabCache.ContainsKey(path) ||
+                    _prefabCache[path].skeletonDataAsset != skeleton.skeletonDataAsset)
+                {
+                    ProcessSkeletonChange(path, skeleton.skeletonDataAsset);
+                }
+            }
         }
     }
 
-    private static void RefreshCache()
+    private static void OnSelectionChanged()
     {
-        _prefabCache.Clear();
-        var allPrefabs = AssetDatabase.FindAssets("t:Prefab")
-            .Select(AssetDatabase.GUIDToAssetPath)
-            .Where(p => p.EndsWith(".prefab"));
-
-        foreach (var path in allPrefabs)
+        // 只处理选中的SkeletonRenderer组件
+        if (Selection.activeGameObject != null)
         {
-            var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
-            var skeleton = prefab.GetComponentInChildren<SkeletonRenderer>();
+            var skeleton = Selection.activeGameObject.GetComponentInChildren<SkeletonRenderer>();
             if (skeleton != null && skeleton.skeletonDataAsset != null)
             {
-                _prefabCache[path] = new CachedPrefabData
+                var path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(skeleton.gameObject);
+                if (!string.IsNullOrEmpty(path) &&
+                    (!_prefabCache.TryGetValue(path, out var cache) ||
+                     cache.skeletonDataAsset != skeleton.skeletonDataAsset))
                 {
-                    skeletonDataAsset = skeleton.skeletonDataAsset,
-                    lastModified = File.GetLastWriteTime(path)
-                };
+                    ProcessSkeletonChange(path, skeleton.skeletonDataAsset);
+                }
             }
         }
     }
 
-    static SkeletonMecanim skeletonMecanim;
+    private static void ProcessSkeletonChange(string prefabPath, SkeletonDataAsset skeletonData)
+    {
+        WriteData(prefabPath);
+        CachePrefab(prefabPath, skeletonData);
+    }
+
     static Character cha;
+    static SkeletonMecanim skeletonMecanim;
 
     private static void WriteData(string path)
     {
         try
         {
             GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
-            if (prefab == null)
-            {
-                Debug.LogWarning($"无法加载Prefab: {path}");
-                return;
-            }
-
             GameObject prefabInstance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
-            if (prefabInstance == null)
-            {
-                Debug.LogWarning($"实例化Prefab失败: {path}");
-                return;
-            }
-
-            // 这里替换为您原来的WriteData实现
-            Debug.Log($"正在处理Prefab: {path}");
 
             cha = prefabInstance.GetComponent<Character>();
             ReadData(prefabInstance);
@@ -251,23 +218,38 @@ public class SkeletonDataMonitor
         }
     }
 
-    [MenuItem("Tools/Spine/Force Refresh All")]
-    private static void ForceRefreshAll()
+    // 监听SkeletonDataAsset文件变化
+    public class SkeletonDataPostprocessor : AssetPostprocessor
     {
-        RefreshCache();
-        var allSkeletonData = _prefabCache.Values
-            .Select(x => x.skeletonDataAsset)
-            .Distinct();
-
-        foreach (var data in allSkeletonData)
+        static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets,
+                                         string[] movedAssets, string[] movedFromAssetPaths)
         {
-            var users = _prefabCache
-                .Where(kv => kv.Value.skeletonDataAsset == data)
-                .Select(kv => kv.Key);
+            foreach (string path in importedAssets)
+            {
+                if (path.EndsWith(".asset"))
+                {
+                    var asset = AssetDatabase.LoadAssetAtPath<SkeletonDataAsset>(path);
+                    if (asset != null && _skeletonToPrefabs.ContainsKey(asset))
+                    {
+                        foreach (var prefabPath in _skeletonToPrefabs[asset])
+                        {
+                            ProcessSkeletonChange(prefabPath, asset);
+                        }
+                    }
+                }
+            }
+        }
+    }
 
-            foreach (var path in users)
+    [MenuItem("Tools/Spine/手动刷新变更")]
+    private static void ForceRefreshModified()
+    {
+        foreach (var kvp in _prefabCache.ToList())
+        {
+            var currentModTime = File.GetLastWriteTime(kvp.Key);
+            if (currentModTime != kvp.Value.lastModified)
             {
-                WriteData(path);
+                ProcessSkeletonChange(kvp.Key, kvp.Value.skeletonDataAsset);
             }
         }
     }