123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- #if UNITY_2018_3_OR_NEWER
- #define SUPPORT_NESTED_PREFAB
- #endif
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using Object = UnityEngine.Object;
- #if UNITY_2017_1_OR_NEWER
- using UnityEditor.SceneManagement;
- using UnityEngine.SceneManagement;
- #endif
- #if SUPPORT_NESTED_PREFAB
- using UnityEditor.Experimental.SceneManagement;
- #endif
- namespace vietlabs.fr2
- {
- public class FR2_SceneCache
- {
- private static FR2_SceneCache _api;
- public static Action onReady;
- public static bool ready = true;
- private Dictionary<Component, HashSet<HashValue>> _cache = new Dictionary<Component, HashSet<HashValue>>();
- public int current;
- public Dictionary<string, HashSet<Component>> folderCache = new Dictionary<string, HashSet<Component>>();
- private List<GameObject> listGO;
- //public HashSet<string> prefabDependencies = new HashSet<string>();
- public Dictionary<GameObject, HashSet<string>> prefabDependencies =
- new Dictionary<GameObject, HashSet<string>>();
- public int total;
- private IWindow window;
- public FR2_SceneCache()
- {
- #if UNITY_2018_1_OR_NEWER
- EditorApplication.hierarchyChanged -= OnSceneChanged;
- EditorApplication.hierarchyChanged += OnSceneChanged;
- #else
- EditorApplication.hierarchyWindowChanged -= OnSceneChanged;
- EditorApplication.hierarchyWindowChanged += OnSceneChanged;
- #endif
- #if UNITY_2018_2_OR_NEWER
- EditorSceneManager.activeSceneChangedInEditMode -= OnSceneChanged;
- EditorSceneManager.activeSceneChangedInEditMode += OnSceneChanged;
- #endif
- #if UNITY_2017_1_OR_NEWER
- SceneManager.activeSceneChanged -= OnSceneChanged;
- SceneManager.activeSceneChanged += OnSceneChanged;
- SceneManager.sceneLoaded -= OnSceneChanged;
- SceneManager.sceneLoaded += OnSceneChanged;
- Undo.postprocessModifications -= OnModify;
- Undo.postprocessModifications += OnModify;
- #endif
- #if SUPPORT_NESTED_PREFAB
- PrefabStage.prefabStageOpened -= prefabOnpen;
- PrefabStage.prefabStageClosing += prefabClose;
- PrefabStage.prefabStageOpened -= prefabOnpen;
- PrefabStage.prefabStageClosing += prefabClose;
- #endif
- }
- public static FR2_SceneCache Api
- {
- get
- {
- if (_api == null)
- {
- _api = new FR2_SceneCache();
- }
- return _api;
- }
- }
-
- private bool _dirty = true;
- public bool Dirty
- {
- get { return _dirty; }
- set { _dirty = value; }
- }
- public Dictionary<Component, HashSet<HashValue>> cache
- {
- get
- {
- if (_cache == null)
- {
- refreshCache(window);
- }
- return _cache;
- }
- }
- public void refreshCache(IWindow window)
- {
- if (window == null)
- {
- return;
- }
- // if(!ready) return;
- this.window = window;
- _cache = new Dictionary<Component, HashSet<HashValue>>();
- folderCache = new Dictionary<string, HashSet<Component>>();
- prefabDependencies = new Dictionary<GameObject, HashSet<string>>();
- ready = false;
- List<GameObject> listRootGO = null;
- #if SUPPORT_NESTED_PREFAB
- if (PrefabStageUtility.GetCurrentPrefabStage() != null)
- {
- GameObject rootPrefab = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot;
- if (rootPrefab != null)
- {
- listRootGO = new List<GameObject> {rootPrefab};
- }
- }
- #else
- #endif
- if (listRootGO == null)
- {
- listGO = FR2_Unity.getAllObjsInCurScene().ToList();
- }
- else
- {
- listGO = new List<GameObject>();
- foreach (GameObject item in listRootGO)
- {
- listGO.AddRange(FR2_Unity.getAllChild(item, true));
- }
- }
- total = listGO.Count;
- current = 0;
- // Debug.Log("refresh cache total " + total);
- EditorApplication.update -= OnUpdate;
- EditorApplication.update += OnUpdate;
- // foreach (var item in FR2_Helper.getAllObjsInCurScene())
- // {
- // // Debug.Log("object in scene: " + item.name);
- // Component[] components = item.GetComponents<Component>();
- // foreach (var com in components)
- // {
- // if(com == null) continue;
- // SerializedObject serialized = new SerializedObject(com);
- // SerializedProperty it = serialized.GetIterator().Copy();
- // while (it.NextVisible(true))
- // {
- // if (it.propertyType != SerializedPropertyType.ObjectReference) continue;
- // if (it.objectReferenceValue == null) continue;
- // if(!_cache.ContainsKey(com)) _cache.Add(com, new HashSet<SerializedProperty>());
- // if(!_cache[com].Contains(it))
- // _cache[com].Add(it.Copy());
- // }
- // }
- // }
- Dirty = false;
- }
- private void OnUpdate()
- {
- for (var i = 0; i < 5 * FR2_Cache.priority; i++)
- {
- if (listGO == null || listGO.Count <= 0)
- {
- //done
- // Debug.Log("done");
- EditorApplication.update -= OnUpdate;
- ready = true;
- Dirty = false;
- listGO = null;
- if (onReady != null)
- {
- onReady();
- }
- if (window != null)
- {
- window.OnSelectionChange();
- }
- return;
- }
- int index = listGO.Count - 1;
- GameObject go = listGO[index];
- if (go == null)
- {
- continue;
- }
- string prefabGUID = FR2_Unity.GetPrefabParent(go);
- if (!string.IsNullOrEmpty(prefabGUID))
- {
- Transform parent = go.transform.parent;
- while (parent != null)
- {
- GameObject g = parent.gameObject;
- if (!prefabDependencies.ContainsKey(g))
- {
- prefabDependencies.Add(g, new HashSet<string>());
- }
- prefabDependencies[g].Add(prefabGUID);
- parent = parent.parent;
- }
- }
- Component[] components = go.GetComponents<Component>();
- foreach (Component com in components)
- {
- if (com == null)
- {
- continue;
- }
- var serialized = new SerializedObject(com);
- SerializedProperty it = serialized.GetIterator().Copy();
- while (it.NextVisible(true))
- {
- if (it.propertyType != SerializedPropertyType.ObjectReference)
- {
- continue;
- }
- if (it.objectReferenceValue == null)
- {
- continue;
- }
- var isSceneObject = true;
- string path = AssetDatabase.GetAssetPath(it.objectReferenceValue);
- if (!string.IsNullOrEmpty(path))
- {
- string dir = Path.GetDirectoryName(path);
- if (!string.IsNullOrEmpty(dir))
- {
- isSceneObject = false;
- if (!folderCache.ContainsKey(dir))
- {
- folderCache.Add(dir, new HashSet<Component>());
- }
- if (!folderCache[dir].Contains(com))
- {
- folderCache[dir].Add(com);
- }
- }
- }
- if (!_cache.ContainsKey(com))
- {
- _cache.Add(com, new HashSet<HashValue>());
- }
- _cache[com].Add(new HashValue
- {target = it.objectReferenceValue, isSceneObject = isSceneObject});
- // if (!_cache.ContainsKey(com)) _cache.Add(com, new HashSet<SerializedProperty>());
- // if (!_cache[com].Contains(it))
- // _cache[com].Add(it.Copy());
- // string path = AssetDatabase.GetAssetPath(it.objectReferenceValue);
- // if (string.IsNullOrEmpty(path)) continue;
- // string dir = System.IO.Path.GetDirectoryName(path);
- // if (string.IsNullOrEmpty(dir)) continue;
- // if (!folderCache.ContainsKey(dir)) folderCache.Add(dir, new HashSet<Component>());
- // if (!folderCache[dir].Contains(com))
- // folderCache[dir].Add(com);
- }
- }
- listGO.RemoveAt(index);
- current++;
- }
- }
- private void OnSceneChanged()
- {
- if (!Application.isPlaying)
- {
- Api.refreshCache(window);
- return;
- }
- SetDirty();
- }
- #if UNITY_2017_1_OR_NEWER
- private UndoPropertyModification[] OnModify(UndoPropertyModification[] modifications)
- {
- for (var i = 0; i < modifications.Length; i++)
- {
- if (modifications[i].currentValue.objectReference != null)
- {
- SetDirty();
- break;
- }
- }
- return modifications;
- }
- #endif
- public void SetDirty()
- {
- Dirty = true;
- }
- public class HashValue
- {
- public bool isSceneObject;
- public Object target;
- //public SerializedProperty pro;
- // public HashValue(SerializedProperty pro, bool isSceneObject)
- // {
- // //this.pro = pro;
- // this.isSceneObject = isSceneObject;
- // }
- }
- #if SUPPORT_NESTED_PREFAB
- private void prefabClose(PrefabStage obj)
- {
- if (!Application.isPlaying)
- {
- Api.refreshCache(window);
- return;
- }
- SetDirty();
- }
- private void prefabOnpen(PrefabStage obj)
- {
- if (!Application.isPlaying)
- {
- Api.refreshCache(window);
- return;
- }
- SetDirty();
- }
- #endif
- #if UNITY_2017_1_OR_NEWER
- private void OnSceneChanged(Scene scene, LoadSceneMode mode)
- {
- OnSceneChanged();
- }
- private void OnSceneChanged(Scene arg0, Scene arg1)
- {
- OnSceneChanged();
- }
- #endif
- }
- }
|