Version: Unity 6.6 (6000.6)
LanguageEnglish
  • C#

HierarchyViewModel.GetDepth

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

Declaration

public int GetDepth(ref HierarchyNode node);

Parameters

Parameter Description
node The hierarchy node.

Returns

int The depth of the hierarchy node.

Description

Determines the depth of a node.

The following example adds an action to a context menu that you can use to select the nearest common ancestor of the GameObjects you have selected in the Hierarchy window. The action appears in the Hierarchy Samples submenu of the context menu. The example uses GetDepth to compare two nodes and advance the deeper one upward when finding the nearest common ancestor of all selected nodes.

To use this example:

  1. Save the script in a folder called Assets/Editor/SelectCommonAncestor. Scripts in an Editor folder can use the Hierarchy module API without additional setup. If you save the script outside of an Editor folder, you must enable the Hierarchy built-in module in the Package Manager window, which also adds the module to your Player builds.
  2. Select two or more GameObjects.
  3. In the Hierarchy window, right-click and select Hierarchy Samples, then Select Common Ancestor.
using Unity.Hierarchy;
using Unity.Hierarchy.Editor;
using UnityEditor;
using UnityEngine.UIElements;

namespace Unity.HierarchySamples.Editor { class SelectCommonAncestor { [InitializeOnLoadMethod] static void Initialize() { HierarchyWindow.PopulateContextMenu += OnPopulateContextMenu; }

static void OnPopulateContextMenu(HierarchyWindow window, HierarchyView view, HierarchyViewItem item, DropdownMenu menu) { menu.AppendAction("Hierarchy Samples/Select Common Ancestor", _ => { HierarchyNode commonAncestor = FindCommonAncestor(view);

if (commonAncestor != HierarchyNode.Null && commonAncestor != view.ViewModel.GetRoot()) { view.SetSelection(commonAncestor); view.Frame(commonAncestor); window.UpdateEditorSelection(); } }, _ => view.ViewModel.HasFlagsCount(HierarchyNodeFlags.Selected) < 2 ? DropdownMenuAction.Status.Disabled : DropdownMenuAction.Status.Normal); }

static HierarchyNode FindCommonAncestor(HierarchyView view) { HierarchyViewModel viewModel = view.ViewModel;

// The view is a DFS pre-order flattening, so each subtree occupies a contiguous // index range. Therefore LCA(set) == LCA(min-index node, max-index node) — one // linear scan replaces the previous O(N·D) pairwise fold. int minIndex = int.MaxValue; int maxIndex = int.MinValue; HierarchyNode leftmost = HierarchyNode.Null; HierarchyNode rightmost = HierarchyNode.Null;

foreach (HierarchyNode node in viewModel.EnumerateNodesWithFlags(HierarchyNodeFlags.Selected)) { int index = viewModel.IndexOf(node); if (index < minIndex) { minIndex = index; leftmost = node; } if (index > maxIndex) { maxIndex = index; rightmost = node; } }

if (leftmost == HierarchyNode.Null) return HierarchyNode.Null;

HierarchyNode lca = FindPairwiseLCA(viewModel, leftmost, rightmost);

// A selected node isn't considered its own ancestor, so return its parent instead. if (lca != HierarchyNode.Null && viewModel.HasFlags(lca, HierarchyNodeFlags.Selected)) lca = viewModel.GetParent(lca);

return lca; }

static HierarchyNode FindPairwiseLCA(HierarchyViewModel viewModel, HierarchyNode node1, HierarchyNode node2) { // Move the deeper node up until both nodes are at the same depth, then advance both together in a single loop. while (node1 != node2 && node1 != HierarchyNode.Null && node2 != HierarchyNode.Null) { int depthA = viewModel.GetDepth(node1); int depthB = viewModel.GetDepth(node2); if (depthA >= depthB) { node1 = viewModel.GetParent(node1); } if (depthB >= depthA) { node2 = viewModel.GetParent(node2); } }

return node1; } } }