- Home /
How can I see script dependencies?
I've recently joined a project as a coder and most of the scripts are in the Scripts folder. Sometimes I come across scripts that have duplicates and I want to delete one of them, but I cant figure out how I can see WHERE that script is beeing used. Other objects in Unity have the action "Select dependencies", but this doesnt seem to work for Scripts.
Answer by JDonavan 1 · Feb 18, 2010 at 06:06 PM
AngryAnt has a great script on his site that does the trick:
Looks like you need to clean up your code segment, but yes, AngryAnt's ComponentLister script will do the trick. You can find the post here: http://angryant.com/general/tipsandtricks/where-did-that-component-go/
Yeah I tried cleaning it up. Every time it left something out.
Answer by duck · Dec 30, 2009 at 08:06 PM
I'm pretty sure this is not possible. My reasoning for this is that all scripts are included at runtime, and therefore all scripts are potentially available as types which could potentially be instantiated at runtime. In order for the editor to know whether any particular scripts are used or not, it would have to be able to somehow parse every possible runtime permutation of your code.
consider:
gameObject.AddComponent ("FoobarScript_" + Random.Range(a,b).ToString());
The editor would have to work out every potential value for a & b, before knowing which scripts might potentially be called on! :)
Answer by jashan · Jan 01, 2010 at 10:39 PM
This should be possible with editor scripting - but I think it's not trivial:
You'd have to go through all your scenes. Among other things, you'd use EditorApplication.OpenScene to do this. In the scenes, you should be able to use Object.FindObjectsOfType with the type you're looking for, to get all game objects that have the script you're looking for attached (actually, you get the components - but from there you can easily get the actual game object; and the hierarchy of the game objects is stored in the "transform" attribute of the components which the inherit from Component).
You should be able to select those objects with Selection.gameObjects - but since you're iterating through the scenes that won't help you much, so it's probably better to simply log the names of the game objects and maybe iterate through their transform.parent to get the full path. I haven't tried setting Selection.gameObjects - but the scripting reference doesn't say it's read-only so that should work (if you want to just do this for a single scene, that sure would be nice).
Finally, you'd have to check out all the prefabs in the project. One approach might be simple iterating through the file structure (that could be done with standard .NET API calls - DirectoryInfo.GetDirectories is one of the methods you'd be using for that) and then using AssetDatabase.LoadAssetAtPath to get "living instances" of any prefab and then checking if those contain the script you're looking for (via GetComponent - if it doesn't return null for the given type, the script is used).
I'm not sure this will all work (and you'll probably need a bit more than what I've linked here), and when it works (which I would hope) it'll be a bit of work to implement this - but it's certainly worth a try and would be a great example of the power of editor scripting ;-)
Answer by Jan Oonk 1 · Mar 04, 2011 at 10:59 PM
In my Unity 3.2 it gave some errors when switching Scenes while the Window was open. Plus I wanted to search the component quickly so I have added sorting to the components and the GameObjects it's attached to. Furthermore I rendered the script component in a different color so you could quickly identify them. I also added auto Refresh, filter on name and filter on script components. This is my first EditorWindow script modification try and my first C# Unity thingy. Original idea and code by AngryAnt.
Here's the fixed and modified script:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class ComponentLister : EditorWindow
{
bool forceRefresh=false;
private bool onlyScripts=false;
private string filterComponent="";
private SortedList sets = new SortedList(new myReverserClass());
private ArrayList scripts = new ArrayList();
private Vector2 scrollPosition;
public class myReverserClass : IComparer {
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
public int Compare( System.Object x, System.Object y ) {
return ( (new CaseInsensitiveComparer()).Compare( ((System.Type)x).Name, ((System.Type)y).Name ) );
}
}
[ MenuItem( "Component/Component lister" ) ]
public static void Launch()
{
ComponentLister window = (ComponentLister)GetWindow( typeof( ComponentLister ) );
window.forceRefresh=true;
window.Show();
}
public void UpdateList()
{
Object[] objects;
sets.Clear();
scripts.Clear();
objects = FindObjectsOfType( typeof( Component ) );
foreach( Component component in objects )
{
if (component is MonoBehaviour) {
//Debug.Log(component.GetType() + " attached to "+component.name);
scripts.Add(component.GetType());
}
if( !sets.ContainsKey( component.GetType() ) )
{
sets.Add(component.GetType(),new ArrayList());
}
int i=sets.IndexOfKey(component.GetType());
( ( ArrayList )sets.GetByIndex(i)).Add( (string)component.gameObject.name );
}
foreach( Component component in objects )
{
int i=sets.IndexOfKey(component.GetType());
( ( ArrayList )sets.GetByIndex(i)).Sort();
}
}
public void OnHierarchyChange() {
//Debug.Log("OnHierarchyChange");
UpdateList();
Repaint();
forceRefresh = true;
}
public void OnGUI()
{
GUILayout.BeginHorizontal( GUI.skin.GetStyle( "Box" ) );
GUILayout.Label( "Components in scene:" );
GUILayout.FlexibleSpace();
if( GUILayout.Button( "Refresh" ) || forceRefresh )
{
//if (forceRefresh) Debug.Log("forceRefresh");
forceRefresh=false;
UpdateList();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal( GUI.skin.GetStyle( "Box" ) );
filterComponent = EditorGUILayout.TextField ("Filter:", filterComponent);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal( GUI.skin.GetStyle( "Box" ) );
onlyScripts = EditorGUILayout.Toggle("Show only scripts", onlyScripts);
GUILayout.EndHorizontal();
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
foreach( System.Type type in sets.Keys )
{
if (type.Name.ToLower().Contains(filterComponent.ToLower())) {
bool showGameObjects=false;
if (scripts.Contains(type)) {
GUI.contentColor = Color.yellow;
GUILayout.Label( type.Name + " (Script):" );
showGameObjects=true;
}
else if (!onlyScripts){
GUI.contentColor = Color.white;
GUILayout.Label( type.Name + ":" );
showGameObjects=true;
}
if (showGameObjects) {
GUI.contentColor = Color.white;
foreach( string gameObject in ( ArrayList )sets[ type ] )
{
if( GUILayout.Button( gameObject ) )
{
Selection.activeObject = GameObject.Find(gameObject);
}
}
}
}
}
GUILayout.EndScrollView();
}
}
Egads, this is brilliant! Thanks much to all who wrote and expanded on this. Loving the ability to filter. Super useful tool!
Answer by Skjalg Sturlasson Maehre · Jan 01, 2010 at 05:28 PM
I'm sorry if I didn't phrase my question correctly, and that it was unclear. Since scripts are added to gameobjects using the unity inspector, I was merely looking for a way to see which gameobjects a certain script had been added to. Now I have to go through every gameobject by hand in the hierarchy or look at prefabs in the Project that I think has some relation to the script and see if they have been added to it.
Your answer
Follow this Question
Related Questions
Unity Editor Scripts: GameObject Added / Removed Event? 1 Answer
How can I preserve static object/data between editor and play? 2 Answers
HideFlags on children of visible objects. 3 Answers
How to record the entire game and user behaviour for a research project? 1 Answer
problem with the digits of my timer 1 Answer