Powerhoof

Find Object References in Unity

Jul 29th, 2016
4,093
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.36 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. using System.IO;
  6.  
  7.  
  8. /// Reference finder - Finds prefabs that reference an object in unity
  9. //      To use, stick this under a folder named "Editor", then right click an object/script in the project window and click "Find References"
  10. //      Made by Dave Lloyd- www.powerhoof.com - but go nuts & use it however you want.
  11. public class ReferenceFinder : EditorWindow
  12. {
  13.     Vector2 m_scrollPosition = Vector2.zero;
  14.     List<GameObject> m_references = new List<GameObject>();
  15.     List<string> m_paths = null;
  16.  
  17.     // Used to queue a call to FindObjectReferences() to avoid doing it mid-layout
  18.     Object m_findReferencesAfterLayout = null;
  19.  
  20.  
  21.     [MenuItem ("Assets/Find References",false,39)]
  22.     static void FindObjectReferences()
  23.     {
  24.         //Show existing window instance. If one doesn't exist, make one.
  25.         ReferenceFinder window = EditorWindow.GetWindow<ReferenceFinder>(true, "Find References", true);
  26.         window.FindObjectReferences(Selection.activeObject);
  27.     }
  28.  
  29.     void OnGUI ()      
  30.     {  
  31.         GUILayout.Space(5);
  32.         m_scrollPosition = EditorGUILayout.BeginScrollView(m_scrollPosition);
  33.  
  34.         GUILayout.BeginHorizontal();
  35.         GUILayout.Label("Found: "+m_references.Count);
  36.         if ( GUILayout.Button("Clear", EditorStyles.miniButton) )
  37.         {
  38.             m_references.Clear();
  39.         }
  40.         GUILayout.EndHorizontal();
  41.  
  42.         GUILayout.Space(5);
  43.  
  44.         for ( int i = m_references.Count-1; i >= 0; --i)
  45.         {                  
  46.             LayoutItem(i, m_references[i] );
  47.         }
  48.        
  49.         EditorGUILayout.EndScrollView();   
  50.  
  51.         if ( m_findReferencesAfterLayout != null )
  52.         {
  53.             FindObjectReferences(m_findReferencesAfterLayout);
  54.             m_findReferencesAfterLayout = null;
  55.         }      
  56.     }
  57.  
  58.  
  59.     void LayoutItem(int i, UnityEngine.Object obj)
  60.     {
  61.         GUIStyle style = EditorStyles.miniButtonLeft;
  62.         style.alignment = TextAnchor.MiddleLeft;
  63.        
  64.         if (  obj != null)
  65.         {
  66.             GUILayout.BeginHorizontal();
  67.  
  68.             if ( GUILayout.Button( obj.name, style ) )
  69.             {                          
  70.                 Selection.activeObject = obj;
  71.                 EditorGUIUtility.PingObject(obj);
  72.             }          
  73.  
  74.             // Use "right arrow" unicode character
  75.             if ( GUILayout.Button( "\u25B6", EditorStyles.miniButtonRight, GUILayout.MaxWidth(20) ) )
  76.             {      
  77.                 m_findReferencesAfterLayout = obj;
  78.             }
  79.            
  80.             GUILayout.EndHorizontal();         
  81.         }
  82.     }
  83.  
  84.     /// Finds references to passed objects and puts them in m_references
  85.     void FindObjectReferences( Object toFind )
  86.     {          
  87.         EditorUtility.DisplayProgressBar("Searching","Generating file paths",0.0f);
  88.  
  89.         //
  90.         // Get all prefabs in the project
  91.         //
  92.         if ( m_paths == null )
  93.         {
  94.             m_paths = new List<string>();
  95.             GetFilePaths("Assets", ".prefab", ref m_paths );
  96.         }
  97.  
  98.         float progressBarPos = 0;
  99.         int numPaths = m_paths.Count;
  100.         int hundredthIteration = Mathf.Max(1,numPaths/100); // So we only update progress bar 100 times, not for every item
  101.  
  102.         string toFindName = AssetDatabase.GetAssetPath(toFind);
  103.         toFindName = System.IO.Path.GetFileNameWithoutExtension (toFindName);
  104.         Object[] tmpArray = new Object[1];
  105.         m_references.Clear();
  106.  
  107.         //
  108.         // Loop through all files, and add any that have the selected object in it's list of dependencies
  109.         //
  110.         for ( int i = 0; i < numPaths; ++i )
  111.         {
  112.             tmpArray[0] = AssetDatabase.LoadMainAssetAtPath(m_paths[i]);
  113.             if ( tmpArray != null && tmpArray.Length > 0 && tmpArray[0] != toFind) // Don't add self
  114.             {
  115.                 Object[] dependencies = EditorUtility.CollectDependencies(tmpArray);
  116.                 if ( System.Array.Exists(dependencies, item=>item == toFind ) )
  117.                 {                      
  118.                     // Don't add if another of the dependencies is already in there
  119.                     m_references.Add(tmpArray[0] as GameObject);
  120.                 }
  121.                
  122.             }
  123.             if ( i % hundredthIteration == 0 )
  124.             {
  125.                 progressBarPos += 0.01f;
  126.                 EditorUtility.DisplayProgressBar("Searching","Searching dependencies",progressBarPos);
  127.             }
  128.         }
  129.  
  130.         EditorUtility.DisplayProgressBar("Searching","Removing redundant references",1);
  131.  
  132.         //
  133.         // Go through the references, get dependencies of each and remove any that have another dependency on the match list. We only want direct dependencies.
  134.         //
  135.         for ( int i = m_references.Count - 1; i >= 0; i-- )
  136.         {
  137.             tmpArray[0] = m_references[i];
  138.             Object[] dependencies = EditorUtility.CollectDependencies(tmpArray);
  139.  
  140.             bool shouldRemove = false;
  141.  
  142.             for ( int j = 0; j < dependencies.Length && shouldRemove == false; ++j )
  143.             {
  144.                 Object dependency = dependencies[j];
  145.                 shouldRemove =  ( m_references.Find( item => item == dependency && item != tmpArray[0] ) != null );
  146.             }
  147.  
  148.             if ( shouldRemove )
  149.                 m_references.RemoveAt(i);
  150.         }
  151.  
  152.         EditorUtility.ClearProgressBar();
  153.     }
  154.  
  155.     /// Recursively find all file paths with particular extention in a directory
  156.     static void GetFilePaths(string startingDirectory, string extention, ref List<string> paths)
  157.     {
  158.         try
  159.         {
  160.             // Add any file paths with the correct extention
  161.             string[] files = Directory.GetFiles(startingDirectory);
  162.             for ( int i = 0; i < files.Length; ++i )
  163.             {
  164.                 string file = files[i];
  165.                 if ( file.EndsWith(extention) )
  166.                 {
  167.                     paths.Add(file);
  168.                 }
  169.             }
  170.  
  171.             // Recurse for all directories
  172.             string[] directories = Directory.GetDirectories(startingDirectory);
  173.             for ( int i = 0; i < directories.Length; ++i )
  174.             {
  175.                 GetFilePaths(directories[i], extention, ref paths);
  176.             }
  177.         }
  178.         catch (System.Exception excpt)
  179.         {
  180.             Debug.LogError(excpt.Message);
  181.         }
  182.     }
  183.  
  184. }
Add Comment
Please, Sign In to add comment