예제 #1
0
    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);
            }
        }
    }
예제 #5
0
    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();
    }
예제 #6
0
 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);
                }
            }
        }
    }
예제 #8
0
    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);
        }
    }
예제 #9
0
    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);
    }
예제 #11
0
    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();
    }
예제 #12
0
    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;
        }
    }
예제 #14
0
    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);
                    }
                }
            }
        }
    }
예제 #16
0
    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);
        }
    }
예제 #17
0
    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);
    }
예제 #18
0
    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);
            }
        }
    }
예제 #19
0
 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));
 }
예제 #21
0
 public void CreateReferenceTargetNode(UnityEngine.Object refTarget)
 {
     _refTargetNode = new DependencyViewerNode(refTarget);
 }