3
\$\begingroup\$

I'm going through the code of an open-source Unity project that uses Scriptable Objects as event channels. Currently, when I see a script raise an event (broadcast) through a SO channel, I have no way of finding out which scripts listen on that channel. I'm aware of the "Find references in scene" option, but the listeners are unlikely to all be in the same scene.

Is there a way to find references to a Scriptable Object in ALL scenes, or another way to do what I'm looking for?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ If you are looking for a way to find all hardwired(serialized) references to an asset then I find the linked below github repo very helpful. But if your SO events use UnityEvent I don't think it tracks those, only "direct" inspector references. github.com/networm/FindReferencesInProject \$\endgroup\$ Commented Aug 30, 2023 at 7:36
  • 1
    \$\begingroup\$ @Nikaas that could be the seed of an answer. I'd bet one could modify that code to also look for UntiyEvents and iterate their listeners with GetPersistentTarget()... \$\endgroup\$ Commented Aug 30, 2023 at 13:28

1 Answer 1

0
\$\begingroup\$

Unity has an API for checking an asset's dependencies, but no API that I am aware of for finding references (other than GUI tools which in my experience do not work correctly in any version of the Unity Editor). To find references to an asset targetObject, we have to check every other asset to see if targetObject is in that asset's dependencies.

var targetPath = AssetDatabase.GetAssetPath(targetObject);

var assetGUIDs = AssetDatabase.FindAssets("t:Object");
var assetPaths = new List<string>();
foreach (var guid in guids) {
    var path = AssetDatabase.GUIDToAssetPath(guid);
    assetPaths.Add(path);
}

var results = new List<string>();
foreach (var assetPath in assetPaths) {
    var dependencyPaths = AssetDatabase.GetDependencies(assetPath);
    foreach (var dependencyPath in dependencyPaths) {
        // If the asset we're currently looking at has a dependency on our target asset,
        // add the asset we're looking at to the results list.
        if (dependencyPath == targetPath) {
            results.add(assetPath);
            break;
        }
    }
}

// Next we would print the matches to the console, or display them in some Editor GUI.
OutputResults(results);

This is extremely slow for a large project. My example here is not optimized at all - you can trim down some time by skipping any asset that can't have a dependency (e.g. AudioClip or Texture2D).

If you're planning to search for references to several different assets back-to-back, it's a good idea to cache all of the references you find to any object in a dictionary - just remember that the cache may need to be rebuilt if you move, remove, or modify anything.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.