private static void GetContour( DependencyViewerNode node, int depth, DependencyViewerNode.NodeInputSide childrenSide, Func <float, float, float> getContourCallback, float modSum, ref Dictionary <int /* depth */, float /* minY */> values) { if (!values.ContainsKey(depth)) { values.Add(depth, node.Position.y + modSum); } else { values[depth] = getContourCallback(values[depth], node.Position.y + modSum); } modSum += node.Mod; var children = node.GetInputNodesFromSide(childrenSide); foreach (var child in children) { GetContour(child, depth + 1, childrenSide, getContourCallback, modSum, ref values); } }
public void FindDependencies(DependencyViewerNode node, int depth = 1) { if (node.TargetObject is GameObject) { GameObject targetGameObject = node.TargetObject as GameObject; Component[] components = targetGameObject.GetComponents <Component>(); for (int i = 0; i < components.Length; ++i) { FindDependencies(node, components[i], depth); } if (DependencyResolverUtility.IsPrefab(node.TargetObject)) { UDGV.GameObjectUtility.ForeachChildrenGameObject(targetGameObject, (childGo) => { components = childGo.GetComponents <Component>(); for (int i = 0; i < components.Length; ++i) { FindDependencies(node, components[i], depth, targetGameObject); } }); } } else { FindDependencies(node, node.TargetObject, depth); } }
private IEnumerable <DependencyViewerOperation> FindReferencesOnUnityObject( DependencyViewerNode node, UnityEngine.Object obj, AssetDependencyResolverOperation op, GameObject prefabRoot = null) { SerializedObject objSO = new SerializedObject(obj); SerializedProperty sp = objSO.GetIterator(); while (sp.NextVisible(true)) { if (IsPropertyADependency(sp, node)) { // Reference found! DependencyViewerNode reference = new DependencyViewerNode(obj); DependencyViewerGraph.CreateNodeLink(reference, node); if (prefabRoot != null) { reference.SetAsPrefabContainerInfo(prefabRoot, (obj as Component).gameObject.name); } } ++op.numProcessedProperties; if (op.numProcessedProperties > NumAssetPropertiesReferencesResolvedPerFrame) { op.AssetBeingProcessed = obj; op.numProcessedProperties = 0; yield return(op); } } }
private IEnumerable <DependencyViewerOperation> FindReferencesAmongPrefabChildren( DependencyViewerNode node, GameObject gameObject, AssetDependencyResolverOperation op, GameObject prefabRoot) { // Find references among the components of the GameObject... Component[] components = gameObject.GetComponents <Component>(); for (int i = 0; i < components.Length; ++i) { foreach (var operation in FindReferencesOnUnityObject(node, components[i], op, prefabRoot)) { yield return(operation); } } // ...then make same thing on children Transform trans = gameObject.transform; for (int i = 0; i < trans.childCount; ++i) { GameObject child = trans.GetChild(i).gameObject; foreach (var operation in FindReferencesAmongPrefabChildren(node, child, op, prefabRoot)) { yield return(operation); } } }
private void DrawNode(DependencyViewerNode node) { Rect boxRect = new Rect(GetRelativePosition(node.Position), node.GetSize()); Rect localWindowRect = GetLocalWindowRect(); if (!localWindowRect.Overlaps(boxRect)) { //Debug.Log("Node " + node.Name + " not drawn"); return; } GUI.Box(boxRect, GUIContent.none, GUI.skin.FindStyle("flow node 0")); DrawNodeTitleBar(node, boxRect); Rect boxInsideRect = new Rect( boxRect.x + NodeInsidePadding.x, boxRect.y + NodeInsidePadding.y + EditorGUIUtility.singleLineHeight, boxRect.width - NodeInsidePadding.x * 2, boxRect.height - NodeInsidePadding.y * 2); GUILayout.BeginArea(boxInsideRect); { bool allowSceneObjects = false; EditorGUILayout.ObjectField(node.TargetObject, node.TargetObject.GetType(), allowSceneObjects); if (node.PrefabContainer != null) { DrawPrefabContainer(node); } } GUILayout.EndArea(); }
public static void ForeachNode_PostOrderTraversal( DependencyViewerNode rootNode, DependencyViewerNode.NodeInputSide side, Action <PostOrderTraversalData> callback) { ForeachNode_PostOrderTraversal(null, rootNode, side, callback, 0, 0); }
private void FindDependencies(DependencyViewerNode node, UnityEngine.Object obj, int depth = 1, GameObject prefabRoot = null) { SerializedObject targetObjectSO = new SerializedObject(obj); SerializedProperty sp = targetObjectSO.GetIterator(); while (sp.NextVisible(true)) { if (sp.propertyType == SerializedPropertyType.ObjectReference && sp.objectReferenceValue != null && IsObjectAllowedBySettings(sp.objectReferenceValue)) { // Dependency found! DependencyViewerNode dependencyNode = new DependencyViewerNode(sp.objectReferenceValue); DependencyViewerGraph.CreateNodeLink(node, dependencyNode); if (prefabRoot != null) { Component comp = obj as Component; dependencyNode.SetAsPrefabContainerInfo(prefabRoot, comp.gameObject.name); } if (depth > 1) { FindDependencies(dependencyNode, sp.objectReferenceValue, depth - 1); } } } }
private void CenterNodesBetween(DependencyViewerNode node, DependencyViewerNode sibling, DependencyViewerNode.NodeInputSide treeSide, int depth) { int firstNodeIdx = sibling.GetSiblingIndex(treeSide); int lastSiblingNodeIdx = node.GetSiblingIndex(treeSide); int numNodesBetween = (lastSiblingNodeIdx - firstNodeIdx) - 1; if (numNodesBetween > 0) { float distanceBetweenNodes = (node.Position.y - sibling.Position.y) / (numNodesBetween + 1); int count = 1; for (int i = firstNodeIdx + 1; i < lastSiblingNodeIdx; ++i) { var middleNode = node.GetParent(treeSide).GetChildren(treeSide)[i]; float desiredY = sibling.Position.y + (distanceBetweenNodes * count); float offset = desiredY - middleNode.Position.y; middleNode.SetPositionY(middleNode.Position.y + offset); middleNode.Mod += offset; ++count; } CheckForConflicts(node, depth, treeSide); } }
private void CalculateFinalPositions(DependencyViewerNode node, DependencyViewerNode.NodeInputSide treeSide, float modSum = 0) { node.SetPositionY(node.Position.y + modSum); modSum += node.Mod; foreach (var child in node.GetChildren(treeSide)) { CalculateFinalPositions(child, treeSide, modSum); } }
private void ForeachChildrenRecursively(NodeInputSide treeSide, DependencyViewerNode node, Action <DependencyViewerNode> onEachNodeCallback) { var children = node.GetChildren(treeSide); for (int i = 0; i < children.Count; ++i) { ForeachChildrenRecursively(treeSide, children[i], onEachNodeCallback); } onEachNodeCallback(node); }
private void DrawPrefabContainer(DependencyViewerNode node) { bool allowSceneObjects = false; EditorGUILayout.BeginHorizontal(); { GUIContent label = new GUIContent("Prefab", $"Prefab reference, on GameObject named '{node.GameObjectNameAsPrefabChild}'"); EditorGUILayout.LabelField(label, GUILayout.Width(40)); EditorGUILayout.ObjectField(node.PrefabContainer, typeof(GameObject), allowSceneObjects); } EditorGUILayout.EndHorizontal(); }
internal static void CreateNodeLink(DependencyViewerNode leftNode, DependencyViewerNode rightNode) { if (!leftNode.RightInputs.Contains(rightNode)) { leftNode.RightInputs.Add(rightNode); } if (!rightNode.LeftInputs.Contains(leftNode)) { rightNode.LeftInputs.Add(leftNode); } }
private IEnumerable <DependencyViewerOperation> FindReferencesAmongGameObjects(DependencyViewerNode node, List <Scene> scenes) { AssetDependencyResolverOperation operationStatus = new AssetDependencyResolverOperation(); operationStatus.node = node; List <GameObject> allGameObjects = GetAllGameObjectsFromScenes(scenes); operationStatus.numTotalAssets = allGameObjects.Count; int numPropertiesCheck = 0; for (int i = 0; i < allGameObjects.Count; ++i) { GameObject currentGo = allGameObjects[i]; operationStatus.AssetBeingProcessed = currentGo; Component[] components = currentGo.GetComponents <Component>(); for (int componentIndex = 0; componentIndex < components.Length; ++componentIndex) { Component component = components[componentIndex]; if (component == null) { continue; } SerializedObject componentSO = new SerializedObject(component); SerializedProperty componentSP = componentSO.GetIterator(); while (componentSP.NextVisible(true)) { // Reference found! if (componentSP.propertyType == SerializedPropertyType.ObjectReference && componentSP.objectReferenceValue == node.TargetObject && IsObjectAllowedBySettings(component)) { DependencyViewerNode referenceNode = new DependencyViewerNode(component); DependencyViewerGraph.CreateNodeLink(referenceNode, node); } ++numPropertiesCheck; if (numPropertiesCheck > NumAssetPropertiesReferencesResolvedPerFrame) { numPropertiesCheck = 0; yield return(operationStatus); } } } ++operationStatus.numProcessedAssets; } }
private void DrawNodeLinks(DependencyViewerNode node, List <DependencyViewerNode> inputs, NodeInputSide inputSide) { for (int i = 0; i < inputs.Count; ++i) { DependencyViewerNode inputNode = inputs[i]; DependencyViewerNode leftNode = (inputSide == NodeInputSide.Left ? node : inputNode); DependencyViewerNode rightNode = (inputSide == NodeInputSide.Right ? node : inputNode); Vector2 start = GetRelativePosition(leftNode.GetLeftInputAnchorPosition()); Vector2 end = GetRelativePosition(rightNode.GetRightInputAnchorPosition()); Drawing.DrawLine(start, end, LinkColor, LinkWidth); DrawNodeLinks( inputNode, inputSide == NodeInputSide.Left ? inputNode.LeftInputs : inputNode.RightInputs, inputSide); } }
private IEnumerable <DependencyViewerOperation> FindReferencesAmongAssets(DependencyViewerNode node) { string[] excludeFilters = _settings.ExcludeAssetFilters.Split(','); var allLocalAssetPaths = from assetPath in AssetDatabase.GetAllAssetPaths() where assetPath.StartsWith("Assets/") && !IsAssetPathExcluded(assetPath, ref excludeFilters) select assetPath; AssetDependencyResolverOperation operationStatus = new AssetDependencyResolverOperation { node = node, numTotalAssets = allLocalAssetPaths.Count() }; foreach (string assetPath in allLocalAssetPaths) { ++operationStatus.numProcessedAssets; UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(assetPath); if (obj != null) { bool isPrefab = (obj is GameObject); if (isPrefab) { GameObject prefab = obj as GameObject; foreach (var op in FindReferencesAmongPrefabChildren(node, prefab, operationStatus, prefab)) { yield return(op); } } else { foreach (var op in FindReferencesOnUnityObject(node, obj, operationStatus)) { yield return(op); } } } } }
private void CheckForConflicts(DependencyViewerNode node, int depth, DependencyViewerNode.NodeInputSide treeSide) { float minDistance = node.GetHeight() + DependencyViewerGraphDrawer.DistanceBetweenNodes.y; float shiftValue = 0.0f; var nodeContour = new Dictionary <int, float>(); TreeLayout.GetStartContour(node, depth, treeSide, 0, ref nodeContour); var sibling = node.GetFirstSibling(treeSide); while (sibling != null && sibling != node) { var siblingContour = new Dictionary <int, float>(); TreeLayout.GetEndContour(sibling, depth, treeSide, 0, ref siblingContour); int maxContourDepth = Mathf.Min(siblingContour.Keys.Max(), nodeContour.Keys.Max()); for (int level = depth + 1; level <= maxContourDepth; ++level) { float distance = nodeContour[level] - siblingContour[level]; if (distance + shiftValue < minDistance) { shiftValue = minDistance - distance; } } if (shiftValue > 0) { node.SetPositionY(node.Position.y + shiftValue); node.Mod += shiftValue; CenterNodesBetween(node, sibling, treeSide, depth); shiftValue = 0; } sibling = sibling.GetNextSibling(treeSide); } }
private static void ForeachNode_PostOrderTraversal( DependencyViewerNode parentNode, DependencyViewerNode rootNode, DependencyViewerNode.NodeInputSide side, Action <PostOrderTraversalData> callback, int childIdx, int depth) { List <DependencyViewerNode> children = rootNode.GetInputNodesFromSide(side); for (int i = 0; i < children.Count; ++i) { ForeachNode_PostOrderTraversal(rootNode, children[i], side, callback, i, depth + 1); } PostOrderTraversalData data = new PostOrderTraversalData(side) { childIdx = childIdx, currentNode = rootNode, parentNode = parentNode, depth = depth }; callback(data); }
private void DrawNodeTitleBar(DependencyViewerNode node, Rect boxRect) { Rect boxTitleRect = new Rect( boxRect.x, boxRect.y + 4, boxRect.width, EditorGUIUtility.singleLineHeight); GUI.Label(boxTitleRect, node.Name, _titleLabelStyle); if (node != RefTargetNode) { Vector2 buttonSize = Vector2.one * 15; Vector2 padding = new Vector2(10, 5); Rect viewDependencyRect = new Rect(boxRect.x + boxRect.width - (padding.x + buttonSize.x), boxRect.y + padding.y, buttonSize.x, buttonSize.y); if (GUI.Button(viewDependencyRect, new GUIContent("", "View dependency for this object"), GUI.skin.FindStyle("Icon.ExtrapolationContinue"))) { requestViewDependency(node.TargetObject); } } }
public static void GetEndContour(DependencyViewerNode node, int depth, DependencyViewerNode.NodeInputSide childrenSide, float modSum, ref Dictionary <int /* depth */, float /* minY */> values) { GetContour(node, depth, childrenSide, Mathf.Max, modSum, ref values); }
private bool IsPropertyADependency(SerializedProperty sp, DependencyViewerNode node) { return(sp.propertyType == SerializedPropertyType.ObjectReference && sp.objectReferenceValue == node.TargetObject && IsObjectAllowedBySettings(sp.objectReferenceValue)); }
public void CreateReferenceTargetNode(UnityEngine.Object refTarget) { _refTargetNode = new DependencyViewerNode(refTarget); }