Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
15
Question by tnetennba · Aug 12, 2011 at 02:47 PM · referencereferencesasset-storereference-other-objectinverse

How do I find which objects are referencing another?

If I click an object I can select its dependencies but I want to know the inverse of this. For example if I have texture how do I find all the objects that are using that texture.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bonfire-Boy · May 23, 2017 at 09:43 AM 0
Share

I usually do this outside of Unity, on the command line. I get the asset's guid from its meta file, then search for all files containing the guid. You can make a batch/shell script to do it for you.

10 Replies

· Add your reply
  • Sort: 
avatar image
14

Answer by Gotlight · Oct 13, 2016 at 05:29 PM

For example if I have texture how do I find all the objects that are using that texture.

There is a product which allows you to search for usages (inverse to dependencies) in both Project and Scenes, e.g. it offers:

  • Interface for working with exact fields that are using selected asset

  • Search for usages of different asset types: Textures, Scenes, Scripts, Shaders, Materials, Sprites, Prefabs, Sounds...

  • Replacement of asset usages


Asset Store link:

  • https://www.assetstore.unity3d.com/en/#!/content/59997

alt text


usages.png (100.4 kB)
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Yukon · Nov 01, 2016 at 05:35 AM 2
Share

Nice tool! I've got it month ago and I don't know how I'd've got before without it.

avatar image fafase · Jan 16, 2017 at 04:50 AM 0
Share

There you are. I don't often come on UA but I still manage to get your spam$$anonymous$$g :). For those of you not understanding, he does.

avatar image
9

Answer by tnetennba · Aug 12, 2011 at 02:49 PM

This script will allow you to right click an object in the editor and will search your project and highlight the objects that reference it:

 using UnityEngine;
 using System.Collections;
 using UnityEditor;
 using System.Collections.Generic;

 public class ReferenceFilter : EditorWindow
 {
 [MenuItem("Assets/What objects use this?", false, 20)]
 private static void OnSearchForReferences()
 {
     string final = "";
     List<UnityEngine.Object> matches = new List<UnityEngine.Object>();

     int iid = Selection.activeInstanceID;
     if (AssetDatabase.IsMainAsset(iid))
     {
         // only main assets have unique paths
         string path = AssetDatabase.GetAssetPath(iid);
         // strip down the name
         final = System.IO.Path.GetFileNameWithoutExtension(path);
     }
     else
     {
         Debug.Log("Error Asset not found");
         return;
     }

     // get everything
     Object[] _Objects = FindObjectsOfTypeIncludingAssets(typeof(Object));

     //loop through everything
     foreach (Object go in _Objects)
     {
         // needs to be an array
         Object[] g = new Object[1];
         g[0] = go;

         // All objects
         Object[] depndencies = EditorUtility.CollectDependencies(g);
         foreach (Object o in depndencies)
             if (string.Compare(o.name.ToString(), final) == 0)
                 matches.Add(go);// add it to our list to highlight
     }
     Selection.objects = matches.ToArray();
     matches.Clear(); // clear the list 
 }
 }


You will need to place it in an editor folder for this to work.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image roberto_sc · Oct 04, 2013 at 02:12 AM 0
Share

Awesome, really useful! Who wrote this?

avatar image GrayedFox · Jun 10, 2014 at 03:56 PM 0
Share

Great little script -- saved me an awful head ache going through the hundreds of effect we have in our game (some of which share certain assets) and updating their texture sheet animations. Beauty.

avatar image tnetennba · Jun 11, 2014 at 02:47 PM 2
Share

@roberto_sc I did a long time ago now. @GrayedFox you are welcome

avatar image tanzafamilia · Oct 30, 2016 at 10:26 PM 0
Share

Nice script! although it solves the problem in the very basic way only..

avatar image
6

Answer by Daniel-F · Apr 23, 2016 at 03:55 AM

I hacked together a version of @ricardo_arango's script which works in Unity 5.4 and has some additional functionality (optionally find references to any component in any currently-selected GameObjects, and highlight the referencing GameObject when you click the related log entry).

I realise it's not an elegant solution, but it works and I don't have time for elegance right now, so posting in case someone else finds a use for it. Tried to post it as a comment to his answer but it wouldn't submit for some reason.

  using System;
  using System.Reflection;
  using UnityEditor;
  using UnityEngine;
  
  public class BacktraceReference : EditorWindow {
     private Component _theObject;
     bool specificComponent = false;
 
 
     [MenuItem("GameObject/What Objects Reference this?")]
      public static void Init() {
          GetWindow(typeof (BacktraceReference));
      }
  
      public void OnGUI() {
         
         if( specificComponent = GUILayout.Toggle(specificComponent, "Match a single specific component") ) {
             _theObject = EditorGUILayout.ObjectField("Component referenced : ", _theObject, typeof(Component), true) as Component;
             if( _theObject == null )
                 return;
 
             if( GUILayout.Button("Find Objects Referencing it") )
                 FindObjectsReferencing(_theObject);
         }
         else if( GUILayout.Button("Find Objects Referencing Selected GameObjects") ) 
         {
             GameObject[] objects = Selection.gameObjects;
             if( objects==null || objects.Length < 1 ) {
                 GUILayout.Label("Select source object/s in Hierarchy.");
                 return;
             }
             foreach( GameObject go in objects ) {
                 foreach( Component c in go.GetComponents(typeof(Component)) ) {
                     FindObjectsReferencing(c);
                 }
             }
         }
      }
  
      private static void FindObjectsReferencing<T>(T mb) where T : Component {
          var objs = Resources.FindObjectsOfTypeAll(typeof (Component)) as Component[];
          if (objs == null) return;
          foreach (Component obj in objs) {
              FieldInfo[] fields =
                  obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                          BindingFlags.Static);
              foreach (FieldInfo fieldInfo in fields) {
                  if (FieldReferencesComponent(obj, fieldInfo, mb)) {
                      Debug.Log("Ref: Component " + obj.GetType() + " from Object " + obj.name +" references source component "+mb.GetType(), obj.gameObject);
                  }
              }
          }
      }
  
      private static bool FieldReferencesComponent<T>(Component obj, FieldInfo fieldInfo, T mb) where T : Component {
          if (fieldInfo.FieldType.IsArray) {
              var arr = fieldInfo.GetValue(obj) as Array;
              foreach (object elem in arr) {
                  if (elem != null && mb != null && elem.GetType() == mb.GetType()) {
                      var o = elem as T;
                      if (o == mb)
                          return true;
                  }
              }
          }
          else {
              if (fieldInfo.FieldType == mb.GetType()) {
                  var o = fieldInfo.GetValue(obj) as T;
                  if (o == mb)
                      return true;
              }
          }
          return false;
      }
  }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vicenterusso · Aug 01, 2016 at 03:00 AM 0
Share

@daniel-f not working anymore.. (5.4.0)

avatar image zombience vicenterusso · Jul 26, 2017 at 05:24 PM 0
Share

when i tried this it was getting an error on line 59: arr is null just do a null check:

if (arr == null) return;

worked for me after fixing that

avatar image kamran-bigdely · Apr 27, 2017 at 10:06 PM 0
Share

worked for me in 5.5.2f1

avatar image zombience · Jul 26, 2017 at 05:26 PM 0
Share

hey thanks a lot for this. i've been looking around for a starting place to write my own on a project. i need something very tailored to a particular situation, and this is a perfect example of how to get it working.

i've been looking for exactly this type of solution, as the ones posted everywhere rely more on unity's internal editor tools. i knew right out of the gate that i was going to have to get into reflection, and i was a little afraid that i'd have to get into YA$$anonymous$$L parsing. this gets me out of that situation nicely.

thank you!

avatar image
5

Answer by ricardo_arango · Apr 04, 2012 at 12:03 PM

This will work for all loaded objects (Not Assets in the Project):

 using System;
 using System.Reflection;
 using UnityEditor;
 using UnityEngine;
 
 public class BacktraceReference : EditorWindow {
     private Class1 _theObject;
 
     [MenuItem("GameObject/What Objects Reference this?")]
     public static void Init() {
         GetWindow(typeof (BacktraceReference));
     }
 
     public void OnGUI() {
         _theObject = EditorGUILayout.ObjectField("Object referenced : ", _theObject, typeof (Class1), true) as Class1;
         if (_theObject == null) return;
         if (GUILayout.Button("Find Objects Referencing it"))
             FindObjectsReferencing(_theObject);
     }
 
     private static void FindObjectsReferencing<T>(T mb) where T : Component {
         var objs = Resources.FindObjectsOfTypeAll(typeof (Component)) as Component[];
         if (objs == null) return;
         foreach (Component obj in objs) {
             FieldInfo[] fields =
                 obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                         BindingFlags.Static);
             foreach (FieldInfo fieldInfo in fields) {
                 if (FieldReferencesComponent(obj, fieldInfo, mb)) {
                     Debug.Log("Ref: Component " + obj.GetType() + " from Object " + obj.name);
                 }
             }
         }
     }
 
     private static bool FieldReferencesComponent<T>(Component obj, FieldInfo fieldInfo, T mb) where T : Component {
         if (fieldInfo.FieldType.IsArray) {
             var arr = fieldInfo.GetValue(obj) as Array;
             foreach (object elem in arr) {
                 if (elem.GetType() == mb.GetType()) {
                     var o = elem as T;
                     if (o == mb)
                         return true;
                 }
             }
         }
         else {
             if (fieldInfo.FieldType == mb.GetType()) {
                 var o = fieldInfo.GetValue(obj) as T;
                 if (o == mb)
                     return true;
             }
         }
         return false;
     }
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image rocifier · Sep 11, 2013 at 10:41 PM 0
Share

What is Class1?

avatar image ricardo_arango ♦♦ · Sep 12, 2013 at 04:32 PM 0
Share

It's an example of a custom type of the Object you would be looking for. It could be a GameObject, Transform, Renderer, etc. Any reference type that derives from Component

avatar image
3

Answer by ShawnFeatherly · May 21, 2018 at 06:36 PM

I made a script with similar functionality to @Daniel-F. It only handles a single scene file. Yet it handles all type of sub-references well, complex objects, arrays, etc... Tested in 2013.3.1f1 & 5.6.3f1

 using System.Collections.Generic;
 using UnityEngine;
 using System.Linq;
 #if UNITY_EDITOR
 using UnityEditor;

 public class BacktraceReference : EditorWindow
 {
     /// <summary> The result </summary>
     public static List<Component> ReferencingSelection = new List<Component>();

     /// <summary> allComponents in the scene that will be searched to see if they contain the reference </summary>
     private static Component[] allComponents;

     /// <summary> Selection of gameobjects the user made </summary>
     private static GameObject[] selections;

     /// <summary>
     /// Adds context menu to hierarchy window https://answers.unity.com/questions/22947/adding-to-the-context-menu-of-the-hierarchy-tab.html
     /// </summary>
     [UnityEditor.MenuItem("GameObject/Find Objects Referencing This", false, 48)]
     public static void InitHierarchy()
     {
         selections = UnityEditor.Selection.gameObjects;
         BacktraceSelection(selections);
         GetWindow(typeof(BacktraceReference));
     }

     /// <summary>
     /// Display referenced by components in window
     /// </summary>
     public void OnGUI()
     {
         if (selections == null || selections.Length < 1)
         {
             GUILayout.Label("Select source object/s from scene Hierarchy panel.");
             return;
         }

         // display reference that is being checked
         GUILayout.Label(string.Join(", ", selections.Where(go => go != null).Select(go => go.name).ToArray()));

         // handle no references
         if (ReferencingSelection == null || ReferencingSelection.Count == 0)
         {
             GUILayout.Label("is not referenced by any gameobjects in the scene");
             return;
         }

         // display list of references using their component name as the label
         foreach (var item in ReferencingSelection)
         {
             EditorGUILayout.ObjectField(item.GetType().ToString(), item, typeof(GameObject), allowSceneObjects: true);
         }
     }

     // This script finds all objects in scene
     private static Component[] GetAllActiveInScene()
     {
         // Use new version of Resources.FindObjectsOfTypeAll(typeof(Component)) as per https://forum.unity.com/threads/editorscript-how-to-get-all-gameobjects-in-scene.224524/
         var rootObjects = UnityEngine.SceneManagement.SceneManager
             .GetActiveScene()
             .GetRootGameObjects();

         List<Component> result = new List<Component>();
         foreach (var rootObject in rootObjects)
         {
             result.AddRange(rootObject.GetComponentsInChildren<Component>());
         }
         return result.ToArray();
     }

     private static void BacktraceSelection(GameObject[] selections)
     {
         if (selections == null || selections.Length < 1)
             return;

         allComponents = GetAllActiveInScene();
         if (allComponents == null) return;
         ReferencingSelection.Clear();

         foreach (GameObject selection in selections)
         {
             foreach (Component cOfSelection in selection.GetComponents(typeof(Component)))
             {
                 FindObjectsReferencing(cOfSelection);
             }
         }
     }

     private static void FindObjectsReferencing<T>(T cOfSelection) where T : Component
     {
         foreach (Component sceneComponent in allComponents)
         {
             componentReferences(sceneComponent, cOfSelection);
         }
     }

     /// <summary>
     /// Determines if the component makes any references to the second "references" component in any of its inspector fields
     /// </summary>
     private static void componentReferences(Component component, Component references)
     {
         // find all fields exposed in the editor as per https://answers.unity.com/questions/1333022/how-to-get-every-public-variables-from-a-script-in.html
         SerializedObject serObj = new SerializedObject(component);
         SerializedProperty prop = serObj.GetIterator();
         while (prop.NextVisible(true))
         {
             bool isObjectField = prop.propertyType == SerializedPropertyType.ObjectReference && prop.objectReferenceValue != null;
             if (isObjectField && prop.objectReferenceValue == references)
             {
                 ReferencingSelection.Add(component);
             }
         }
     }
 }
 #endif
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image idbrii · Jun 06, 2018 at 11:41 PM 0
Share

To make the editor window more useful, you can add this button to the beginning of OnGUI:

 if (GUILayout.Button("Search current selection"))
 {
     selections = UnityEditor.Selection.gameObjects;
     BacktraceSelection(selections);
 }
avatar image idbrii · Jun 11, 2018 at 05:52 PM 1
Share

This doesn't find inactive game objects. To fix, change GetComponentsInChildren calls to use includeInactive:

 GetComponentsInChildren<Component>(includeInactive: true)

If you have lots of results, you can easily add EditorGUILayout.Begin/EndScrollView to scroll them (I used a try/finally to end without modifying the early returns). You could even try a coroutine to display EditorUtility.DisplayProgressBar and do updates in batches per frame (that's a lot of work so I haven't tried it).

avatar image Bonfire-Boy idbrii · Jun 11, 2018 at 11:06 PM 0
Share

You don't need to use try/finally for that, C#'s using keyword (together with a simple wrapper class) does the same thing more cleanly.

So the class would be something like

 public class EditorScrollView : System.IDisposable
 {
     public EditorScrollView()
     {
         EditorGUILayout.BeginScrollView();        
     }
 
     public void Dispose()
     {
         EditorGUILayout.EndScrollView();        
     } 
  
 }

And then ins$$anonymous$$d of your try/finally you'd just have

 using (new EditorScrollView())
 {
 // stuff in the scrollview
 }

I generally do this for all the start/end paired layout functions. You never have to remember to close a section and you always know they'll close in the right order, plus the code's layout reflects that of the UI. Using lots of nested try/finally blocks for that would be far messier.

avatar image idbrii Bonfire-Boy · Jul 06, 2018 at 12:12 AM 0
Share

Even though it's editor-only code, I tend to avoid allocations in updates (like OnGUI).

However, I think you could change that to a struct and it would be good!

avatar image idbrii · Jul 09, 2018 at 08:30 PM 1
Share

These types of references don't work:

 public GameObject ref;

To include these objects referenced by GameObject ins$$anonymous$$d of Component in results, change componentReferences to look for the gameobject too:

         if (isObjectField
                 && (prop.objectReferenceValue == references // references the component itself
                     || prop.objectReferenceValue == references.gameObject)) // references the component's owner
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Weird problem with referencing game manager 1 Answer

Restoring Static Variables after DontDestroyOnLoad 1 Answer

Newly created scripts cannot be referenced 2 Answers

Can I access a script referenced in another script (without getcomponent)? 5 Answers

Passing reference of transform properties to coroutine animation? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges