Skip to content

Dependency Viewer

Jonathan Schmidt edited this page Aug 24, 2021 · 1 revision

The Dependency Viewer is a new prototype tool that is built on the Search ecosystem. The Dependency Viewer allows a user to always know the dependencies (both Uses and Used by) of any objects (GameObject or asset) that are currently selected. Also, the Dependency Viewer has a lot of useful reports that inform the user about their project: broken dependencies, missing assets, most used assets, etc.

Opening the Dependency Viewer

The Dependency Viewer can be found in the menu Window->Search->Dependency Viewer:

This menu will open the tool in a mode where the global selection is tracked. This means that each time the selection changes, the dependencies of the selected object(s) are displayed.

As soon as you open the Viewer, the Dependency Database will be built. This is asynchronous process that won't block you from using the editor. When dependency indexing is done you will see a log in the Console window:

More information on building the Dependency Database can be found here.

From now on, the Dependency Viewer is ready to be used.

Dependency Viewer Tour

Tracking the current selection

By default, the Dependency Viewer displays which dependencies are Used by the selection and which objects are using any objects in the selection. Each time an item is added or removed from the selection, the Dependency Viewer will update. Notice that we only show direct dependencies, meaning dependencies at a single level of indirection from the selection.

The 3 top items of this menu allow customizing the Tracking Selection Dependency Mode:

  • Selection: Track selection and show both Uses and Used by.

  • Uses: Track selection and show Uses.

  • Uses: Track selection and Show Use by

Note that we show Uses or Used by of GameObjects only in the current scene.

Double clicking

Double clicking on an item in the Dependency Viewer will "explore" all dependencies of this item. This workflow can be used to dig deeper into the dependency graph of a specific object.

Dependency History

As showed in the gif above we store an history of objects that have been explored. Using the 2 History navigation buttons you can come back to previous dependency sets.

Dependency Toolbar

Everything that can be interacted with in the Dependency Viewer is located in the main toolbar. This is where you will find:

  • History navigation buttons: navigate between dependency sets.
  • Scene filter: show or hide dependency GameObjects in the current scene. This can be turned off if you do not need GameObjects or if you feel querying the scene for its dependencies is too slow.
  • Build button: This rebuilds the Dependency Database.
  • Columns filter: to allow a user to show or hide any columns in order to get a more compact view.
  • Report/Mode selection: to allow a user to customize the type of dependencies that are shown (Uses, Used By or both) and to select any Dependency Reports or Dependency Queries that are part of the project.
  • Lock button: to lock the Dependency Viewer on the current set of objects and to stop tracking selection.

We store an history of dependencies that have been explored. Using the 2 History navigation buttons you can come back to previous dependency sets.

Right click on an item

Right clicking on any item shows a menu with useful dependency related actions:

  • Select: this will select the object in the editor.
  • Add to favorite: this will add the item to Favorites. In consequence, the favorited item will always be sorted at the top of any list it is part of (Uses or Used By).
  • Copy GUID: copy the object GUID on the Clipboard.
  • Copy Relative Path: copy the project path of the object on the Clipboard.
  • Copy Absolute Path: copy the absolute path of the object on the Clipboard.

Changing the Column layout

You can slightly tweak the appearance of the Dependency Viewer by right-clicking on a list's (Uses or Used By) column header:

This menu allows you to show or hide any of this list's columns.

Or it can be used to edit the display of a column:

Open in Search

The Open in Search menu item is used to open the (Quick)Search window with the dependency query that was used to populate a specific dependency list.

Most asset dependency query are using the new Dependency Search Provider. All GameObjects query relative to the current scene are using the Scene Search Provider.

Looking at a query is especially useful to explore the way some of the Dependency Reports are built:

Dependency Reports

The Dependency Viewer ships with some Dependency Reports that allows to get a global feel on how assets are used in a project. You can create your own dependency reports using an api described here.

  • Broken Dependencies: this report any assets of GameObjects that references a GUID that doesn't resolve in the Project. This corresponds to the search query dep:is:broken (query ran on the Dependency provider).

  • Missing Dependencies: this shows all GUIDs that are referenced in your project and that do not resolved to an asset. Currently there are not automatic way to fix these references though you can right click on the item and copy the GUID to search it:

  • Unused Assets: shows any assets in your project that is not refered by anything. These assets should be safe to delete.
  • Ignored Assets: shows assets that have been labeled to be ignored by the dependency system.

This section of the menu shows which Search Queries in your project have been labeled as Dependency Query:

Clicking on any of those query will populate the Dependency view with the query results:

Project Browser Integration

Installing the search-extensions packages adds a small Dependency integration to the Project Browser.

Asset usages

We adds next to the names of assets their Used By count (how many times an asset is referenced).

Asset Dependency Right click Menu

When right clicking on an asset, the Dependencies context menu gives a few dependency related actions:

  • Copy GUID: copy the GUID of the asset on the clipboard
  • Find Uses: open the Search window and shows which objects the clicked asset Uses.
  • Find Used By: open the Search window and shows which objects are using the clicked asset.
  • Add to ignored: add the clicked asset to the Ignored list. This asset won't be tracked by the dependency system anymore. You need to rebuild the Dependency Database after modifying the Ignored list.
  • Remove from ignored: remove the clicked asset from the Ignored list. This asset will be tracked by the dependency system. You need to rebuild the Dependency Database after modifying the Ignored list.

Technical Overview

Dependency Database

The Dependency Search Provider crawls all the files in your project and searches for anything resembling an asset reference:

  • Any GUID in a text file (yaml, json, etc);
  • Any token that looks like a filename in a text file (json, cs, shader).

When a GUID is found we try to resolve it against any assets of your project. If an asset is found, we add a hard dependency link between the file containing the GUID and the referenced asset. Filenames are assumed to produce weak reference link: that is links that looks like reference but that could be a false positive.

Updating the Dependency Database

Currently the Dependency Database is not updated automatically if assets changed on disk. You have to manually press the Build button in the Dependency Viewer or used the Window->Search->Rebuild Dependency Index menu.

Extending Dependency Registration

There are currently no way of extending how the system computes its dependency graph but this is something we are looking at.

Creating new Dependency Reports

You can register your own Dependency Reports using the DependencyViewerState attribute. You can then decide how many list views you want to display and provide a Search Context with a query for evaluation. Use the Search Window to tweak your query. Here is an example on how to setup the Unused Assets report:

[DependencyViewerProvider]
internal static DependencyViewerState UnusedAssets(DependencyViewerFlags flags)
{
    // Run this query on the Dependency (dep) Search provider.
    var query = SearchService.CreateContext(new[] { "dep" }, "dep:in=0 is:file -is:package");
    var title = ObjectNames.NicifyVariableName(nameof(UnusedAssets));
    return new DependencyViewerState(title,
        // Thsi query uses a single list with a SearchTable containing 3 columns:
        new DependencyState(title, query, new SearchTable(title, "Name", new[] {
            new SearchColumn(title, "label", "Name") { width = 380 },
            new SearchColumn("Type", "type") { width = 90 },
            new SearchColumn("Size", "size", "size")  { width = 80 }
        }))
    );
}

Dependency Search Query

Alternatively you can provide Dependency query acting as a Dependency report if you add the dependency label to a Search Query Asset. This query can contains a Search table specification and can use any Search providers (even your own).

As an example let's write a Query that lists all direct dependencies of all scenes in my project:

from=select{t:scene, @path}

This query reads as:

  1. Select all scene asset and extract their path
  2. Use the Dependency provider to compute any assets Used by (i.e from) these scenes.

Ensure to have the Expression, Project and Dependencies provider enabled.

In order to have this query avaiable as a Dependency report:

  1. Save the query to disk
  2. Add a dependency label on the query
  3. Test it in the Dependency Viewer