Ejemplo n.º 1
0
        private void ReplaceUnit()
        {
            var oldUnit      = unit;
            var unitPosition = oldUnit.position;
            var preservation = UnitPreservation.Preserve(oldUnit);

            var options = new UnitOptionTree(new GUIContent("Unit"));

            options.reference = reference;

            var activatorPosition = new Rect(e.mousePosition, new Vector2(200, 1));

            var context = this.context;

            LudiqGUI.FuzzyDropdown
            (
                activatorPosition,
                options,
                null,
                delegate(object _option)
            {
                var option = (IUnitOption)_option;

                context.BeginEdit();
                UndoUtility.RecordEditedObject("Replace Unit");
                var graph = oldUnit.graph;
                oldUnit.graph.units.Remove(oldUnit);
                var newUnit      = option.InstantiateUnit();
                newUnit.guid     = Guid.NewGuid();
                newUnit.position = unitPosition;
                graph.units.Add(newUnit);
                preservation.RestoreTo(newUnit);
                option.PreconfigureUnit(newUnit);
                selection.Select(newUnit);
                GUI.changed = true;
                context.EndEdit();
            }
            );
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Flip Object Normals");

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                foreach (var face in pb.facesInternal)
                {
                    face.Reverse();
                }
                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            return(new ActionResult(ActionResult.Status.Success, "Flip Object Normals"));
        }
        protected override ActionResult PerformActionImplementation()
        {
            UndoUtility.RecordSelection("Select Hole");

            ActionResult res = ActionResult.NoSelection;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                bool selectAll            = pb.selectedIndexesInternal == null || pb.selectedIndexesInternal.Length < 1;
                IEnumerable <int> indexes = selectAll ? pb.facesInternal.SelectMany(x => x.indexes) : pb.selectedIndexesInternal;

                List <List <Edge> > holes = ElementSelection.FindHoles(pb, indexes);

                res = new ActionResult(ActionResult.Status.Success, holes.Count > 0 ? string.Format("{0} holes found", holes.Count) : "No Holes in Selection");

                pb.SetSelectedEdges(holes.SelectMany(x => x));
            }

            ProBuilderEditor.Refresh();

            return(res);
        }
Ejemplo n.º 4
0
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            int success = 0;

            UndoUtility.RecordSelection("Subdivide Faces");

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                Face[] faces = pb.Subdivide(pb.selectedFacesInternal);

                pb.ToMesh();

                if (faces != null)
                {
                    success += pb.selectedFacesInternal.Length;
                    pb.SetSelectedFaces(faces);

                    pb.Refresh();
                    pb.Optimize();
                }
            }

            if (success > 0)
            {
                ProBuilderEditor.Refresh();

                return(new ActionResult(ActionResult.Status.Success, "Subdivide " + success + ((success > 1) ? " faces" : " face")));
            }
            else
            {
                Debug.LogWarning("Subdivide faces failed - did you not have any faces selected?");
                return(new ActionResult(ActionResult.Status.Failure, "Subdivide Faces\nNo faces selected"));
            }
        }
Ejemplo n.º 5
0
        public override ActionResult DoAction()
        {
            IEnumerable <ProBuilderMesh> selection;

            if (m_RestrictToSelectedObjects)
            {
                selection = MeshSelection.topInternal;
            }
            else
            {
                selection = Object.FindObjectsOfType <ProBuilderMesh>();
            }

            UndoUtility.RecordSelection("Select Faces with Material");

            HashSet <int> sel = new HashSet <int>(
                MeshSelection.topInternal
                .SelectMany(x => x.selectedFacesInternal.Select(y => y.submeshIndex)));

            List <GameObject> newSelection = new List <GameObject>();

            foreach (var pb in selection)
            {
                IEnumerable <Face> matches = pb.facesInternal.Where(x => sel.Contains(x.submeshIndex));

                if (matches.Any())
                {
                    newSelection.Add(pb.gameObject);
                    pb.SetSelectedFaces(matches);
                }
            }

            Selection.objects = newSelection.ToArray();

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Select Faces with Material"));
        }
        private void InitWindow()
        {
            //window setup
            s_instance            = this;
            titleContent          = new GUIContent("Nody");
            wantsMouseMove        = true;
            minSize               = new Vector2((ToolbarAnimBool.target ? DoozyWindowSettings.Instance.ToolbarExpandedWidth : DoozyWindowSettings.Instance.ToolbarCollapsedWidth) + 300, 300);
            ToolbarAnimBool.value = DoozyWindowSettings.Instance.DynamicToolbarExpanded;

            InitAnimBools();              //initialize the animation bools
            SetGraphMode(GraphMode.None); //set the graph to idle mode
            m_undo = new UndoUtility();   //init the UndoUtility

            //subscribe to events
            EditorApplication.playModeStateChanged += HandleOnPlayModeStateChanged;
            Undo.undoRedoPerformed  = UndoRedoPerformed;
            GraphEvent.OnGraphEvent = HandleOnGraphEvent;

            if (!ReopenCurrentGraph())
            {
                SetView(View.General);
            }
        }
Ejemplo n.º 7
0
        public override INodeReference OnGUI(GUIContent content, INodeReference instance)
        {
            //we presume that INodeRefence is serialized in a Node context
            if (instance == null)
            {
                UnityEditor.EditorGUILayout.LabelField(content.text, "Null NodeReference Instance");
                return(instance);
            }
            var contextNode = context as Node;

            if (contextNode == null || contextNode.graph == null)
            {
                return(instance);
            }
            var graph = contextNode.graph;

            var targets   = graph.allNodes.Where(x => instance.type.IsAssignableFrom(x.GetType()));
            var current   = instance.Get(graph);
            var newTarget = EditorUtils.Popup <Node>(content, current, targets);

            if (newTarget != current)
            {
                UndoUtility.RecordObject(contextUnityObject, "Set Node Reference");
                instance.Set(newTarget);
                foreach (var callbackAtt in attributes.OfType <CallbackAttribute>())
                {
                    var m = contextNode.GetType().RTGetMethod(callbackAtt.methodName);
                    if (m != null)
                    {
                        m.Invoke(contextNode, null);
                    }
                }
                UndoUtility.SetDirty(contextUnityObject);
            }

            return(instance);
        }
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            var def = (SignalDefinition)target;

            if (GUILayout.Button("Add Parameter"))
            {
                EditorUtils.ShowPreferedTypesSelectionMenu(typeof(object), (t) =>
                {
                    UndoUtility.RecordObjectComplete(def, "Add Parameter");
                    def.AddParameter(t.FriendlyName(), t);
                    UndoUtility.SetDirty(def);
                });
            }

            UndoUtility.CheckUndo(def, "Definition");
            var options = new EditorUtils.ReorderableListOptions();

            options.allowRemove        = true;
            options.unityObjectContext = def;
            EditorUtils.ReorderableList(def.parameters, options, (i, picked) =>
            {
                var parameter = def.parameters[i];
                GUILayout.BeginHorizontal();
                parameter.name = UnityEditor.EditorGUILayout.DelayedTextField(parameter.name, GUILayout.Width(150), GUILayout.ExpandWidth(true));
                EditorUtils.ButtonTypePopup("", parameter.type, (t) => { parameter.type = t; });
                GUILayout.EndHorizontal();
            });
            UndoUtility.CheckDirty(def);

            EditorUtils.EndOfInspector();
            if (Event.current.isMouse)
            {
                Repaint();
            }
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Delete Face");

            int count = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                if (pb.selectedFaceCount == pb.facesInternal.Length)
                {
                    Debug.LogWarning("Attempting to delete all faces on this mesh...  I'm afraid I can't let you do that.");
                    continue;
                }

                pb.DeleteFaces(pb.selectedFacesInternal);
                count += pb.selectedFaceCount;

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            MeshSelection.ClearElementSelection();
            ProBuilderEditor.Refresh();

            if (count > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Delete " + count + " Faces"));
            }

            return(new ActionResult(ActionResult.Status.Failure, "No Faces Selected"));
        }
Ejemplo n.º 10
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Flip Face Edges");
            int success  = 0;
            int attempts = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                foreach (Face face in pb.selectedFacesInternal)
                {
                    if (pb.FlipEdge(face))
                    {
                        success++;
                    }
                }

                attempts++;

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            ProBuilderEditor.Refresh();

            if (success > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Flipped " + success + " Edges"));
            }

            return(new ActionResult(ActionResult.Status.Failure, string.Format("Flip Edges\n{0}", attempts > 0 ? "Faces Must Be Quads" : "No Faces Selected")));
        }
Ejemplo n.º 11
0
        public override ActionResult DoAction()
        {
            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Connect Edges");

            foreach (var mesh in MeshSelection.topInternal)
            {
                Edge[] connections;
                Face[] faces;

                res = ConnectElements.Connect(mesh, mesh.selectedEdges, out faces, out connections, true, true);

                if (connections != null)
                {
                    mesh.SetSelectedEdges(connections);
                    mesh.Refresh();
                    mesh.Optimize();
                }
            }

            ProBuilderEditor.Refresh();
            return(res);
        }
Ejemplo n.º 12
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Bridge Edges");

            bool success = false;

            foreach (var mesh in MeshSelection.topInternal)
            {
                if (mesh.selectedEdgeCount == 2)
                {
                    if (mesh.Bridge(mesh.selectedEdges[0], mesh.selectedEdges[1], ProBuilderEditor.s_AllowNonManifoldActions) != null)
                    {
                        success = true;
                        mesh.ToMesh();
                        mesh.Refresh();
                        mesh.Optimize();
                    }
                }
            }

            if (success)
            {
                ProBuilderEditor.Refresh();
                return(new ActionResult(ActionResult.Status.Success, "Bridge Edges"));
            }
            else
            {
                Debug.LogWarning("Failed Bridge Edges.  Bridge Edges requires that only 2 edges be selected, and they must both only have one connecting face (non-manifold).");
                return(new ActionResult(ActionResult.Status.Failure, "Bridge Edges requires that only 2 edges be selected, and they must both only have one connecting face (non-manifold)."));
            }
        }
Ejemplo n.º 13
0
        ///<summary>Generate and return task menu</summary>
        GenericMenu GetMenu(Action <Task> callback)
        {
            var menu     = new GenericMenu();
            var taskType = task.GetType();

            menu.AddItem(new GUIContent("Open Script"), false, () => { EditorUtils.OpenScriptOfType(taskType); });
            menu.AddItem(new GUIContent("Copy"), false, () => { CopyBuffer.SetCache <Task>(task); });

            foreach (var _m in taskType.RTGetMethods())
            {
                var m   = _m;
                var att = m.RTGetAttribute <ContextMenu>(true);
                if (att != null)
                {
                    menu.AddItem(new GUIContent(att.menuItem), false, () => { m.Invoke(task, null); });
                }
            }

            if (taskType.IsGenericType)
            {
                menu = EditorUtils.GetPreferedTypesSelectionMenu(taskType.GetGenericTypeDefinition(), (t) => { callback(Task.Create(t, task.ownerSystem)); }, menu, "Change Generic Type");
            }

            menu.AddSeparator("/");

            menu.AddItem(new GUIContent("Delete"), false, () =>
            {
                if (callback != null)
                {
                    UndoUtility.RecordObject(task.ownerSystem.contextObject, "Delete Task");
                    callback(null);
                }
            });

            return(menu);
        }
Ejemplo n.º 14
0
        ///Duplicate node alone assigned to the provided graph
        public Node Duplicate(Graph targetGraph)
        {
            if (targetGraph == null)
            {
                Logger.LogError("Can't duplicate a Node without providing a Target Graph", LogTag.GRAPH);
                return(null);
            }

            //deep clone
            var newNode = JSONSerializer.Clone <Node>(this);

            UndoUtility.RecordObject(targetGraph, "Duplicate Node");

            targetGraph.allNodes.Add(newNode);
            newNode.inConnections.Clear();
            newNode.outConnections.Clear();

            if (targetGraph == this.graph)
            {
                newNode.position += new Vector2(50, 50);
            }

            newNode._UID  = null;
            newNode.graph = targetGraph;
            BBParameter.SetBBFields(newNode, targetGraph.blackboard);

            foreach (var task in Graph.GetTasksInElement(newNode))
            {
                task.Validate(targetGraph);
            }
            //--

            newNode.Validate(targetGraph);
            UndoUtility.SetDirty(targetGraph);
            return(newNode);
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Merge Faces");

            int success = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                if (pb.selectedFaceCount > 1)
                {
                    success += pb.selectedFaceCount;

                    Face face = MergeElements.Merge(pb, pb.selectedFacesInternal);

                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();

                    pb.SetSelectedFaces(new Face[] { face });
                }
            }

            ProBuilderEditor.Refresh();

            if (success > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Merged " + success + " Faces"));
            }

            return(new ActionResult(ActionResult.Status.Failure, "Merge Faces\nNo Faces Selected"));
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Triangulate Objects");

            foreach (var mesh in MeshSelection.topInternal)
            {
                mesh.ToMesh();
                mesh.ToTriangles(mesh.facesInternal);
                mesh.Refresh();
                mesh.Optimize();
                mesh.ClearSelection();
            }

            ProBuilderEditor.Refresh();

            var c = MeshSelection.selectedObjectCount;

            return(new ActionResult(ActionResult.Status.Success, "Triangulate " + c + (c > 1 ? " Objects" : " Object")));
        }
Ejemplo n.º 17
0
        ///<summary>Return get add variable menu</summary>
        GenericMenu GetAddVariableMenu(IBlackboard bb, UnityEngine.Object contextParent)
        {
            System.Action <System.Type> AddNewVariable = (t) =>
            {
                UndoUtility.RecordObject(contextParent, "Variable Added");
                var name = "my" + t.FriendlyName();
                while (bb.GetVariable(name) != null)
                {
                    name += ".";
                }
                bb.AddVariable(name, t);
                UndoUtility.SetDirty(contextParent);
            };

            System.Action <PropertyInfo> AddBoundProp = (p) =>
            {
                UndoUtility.RecordObject(contextParent, "Variable Added");
                var newVar = bb.AddVariable(p.Name, p.PropertyType);
                newVar.BindProperty(p);
                UndoUtility.SetDirty(contextParent);
            };

            System.Action <FieldInfo> AddBoundField = (f) =>
            {
                UndoUtility.RecordObject(contextParent, "Variable Added");
                var newVar = bb.AddVariable(f.Name, f.FieldType);
                newVar.BindProperty(f);
                UndoUtility.SetDirty(contextParent);
            };

            System.Action AddSeparator = () =>
            {
                UndoUtility.RecordObject(contextParent, "Separator Added");
                bb.AddVariable("Separator (Double Click To Rename)", new VariableSeperator());
                UndoUtility.SetDirty(contextParent);
            };

            var menu = new GenericMenu();

            menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), AddNewVariable, menu, "New", true);

            if (bb.propertiesBindTarget != null)
            {
                foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags == 0))
                {
                    menu = EditorUtils.GetInstanceFieldSelectionMenu(comp.GetType(), typeof(object), AddBoundField, menu, "Bound (Self)");
                    menu = EditorUtils.GetInstancePropertySelectionMenu(comp.GetType(), typeof(object), AddBoundProp, false, false, menu, "Bound (Self)");
                }
                menu.AddSeparator("Bound (Self)/");
            }
            foreach (var type in TypePrefs.GetPreferedTypesList())
            {
                if (bb.propertiesBindTarget != null && typeof(UnityEngine.Component).RTIsAssignableFrom(type))
                {
                    menu = EditorUtils.GetInstanceFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Self)");
                    menu = EditorUtils.GetInstancePropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Self)");
                }
                menu = EditorUtils.GetStaticFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Static)");
                menu = EditorUtils.GetStaticPropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Static)");
            }

            menu.AddSeparator("/");
            menu.AddItem(new GUIContent("Add Header Separator"), false, () => { AddSeparator(); });
            return(menu);
        }
Ejemplo n.º 18
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            int splitCount = 0;

            UndoUtility.RecordSelection("Split Vertices");

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                // loose verts to split
                List <int> tris = new List <int>(mesh.selectedIndexesInternal);

                if (mesh.selectedFacesInternal.Length > 0)
                {
                    int[] sharedVertexHandles = new int[mesh.selectedIndexesInternal.Length];

                    // Get shared index index for each vert in selection
                    for (int i = 0; i < mesh.selectedIndexesInternal.Length; i++)
                    {
                        sharedVertexHandles[i] = mesh.GetSharedVertexHandle(mesh.selectedIndexesInternal[i]);
                    }

                    // cycle through selected faces and remove the tris that compose full faces.
                    foreach (Face face in mesh.selectedFacesInternal)
                    {
                        List <int> faceSharedIndexes = new List <int>();

                        for (int j = 0; j < face.distinctIndexesInternal.Length; j++)
                        {
                            faceSharedIndexes.Add(mesh.GetSharedVertexHandle(face.distinctIndexesInternal[j]));
                        }

                        List <int> usedTris = new List <int>();
                        for (int i = 0; i < sharedVertexHandles.Length; i++)
                        {
                            if (faceSharedIndexes.Contains(sharedVertexHandles[i]))
                            {
                                usedTris.Add(mesh.selectedIndexesInternal[i]);
                            }
                        }

                        // This face *is* composed of selected tris.  Remove these tris from the loose index list
                        foreach (int i in usedTris)
                        {
                            if (tris.Contains(i))
                            {
                                tris.Remove(i);
                            }
                        }
                    }
                }

                // Now split the faces, and any loose vertices
                mesh.DetachFaces(mesh.selectedFacesInternal);

                splitCount += mesh.selectedIndexesInternal.Length;
                mesh.SplitVertices(mesh.selectedIndexesInternal);

                // Reattach detached face vertices (if any are to be had)
                if (mesh.selectedFacesInternal.Length > 0)
                {
                    mesh.WeldVertices(mesh.selectedFacesInternal.SelectMany(x => x.indexes), Mathf.Epsilon);
                }

                // And set the selected triangles to the newly split
                List <int> newTriSelection = new List <int>(mesh.selectedFacesInternal.SelectMany(x => x.indexes));
                newTriSelection.AddRange(tris);
                mesh.SetSelectedVertices(newTriSelection.ToArray());

                mesh.ToMesh();
                mesh.Refresh();
                mesh.Optimize();
            }

            ProBuilderEditor.Refresh();

            if (splitCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Split " + splitCount + (splitCount > 1 ? " Vertices" : " Vertex")));
            }
            else
            {
                return(new ActionResult(ActionResult.Status.Failure, "Split Vertices\nInsuffient Vertices Selected"));
            }
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Offset Elements(s)");

            var handleRotation = MeshSelection.GetHandleRotation();

            foreach (var group in MeshSelection.elementSelection)
            {
                var mesh      = group.mesh;
                var positions = mesh.positionsInternal;
                var offset    = s_Translation.value;

                switch (s_CoordinateSpace.value)
                {
                case CoordinateSpace.World:
                case CoordinateSpace.Handle:
                {
                    var pre  = mesh.transform.localToWorldMatrix;
                    var post = mesh.transform.worldToLocalMatrix;

                    if (s_CoordinateSpace.value == CoordinateSpace.Handle)
                    {
                        offset = handleRotation * offset;
                    }

                    foreach (var index in mesh.selectedCoincidentVertices)
                    {
                        var p = pre.MultiplyPoint3x4(positions[index]);
                        p += offset;
                        positions[index] = post.MultiplyPoint3x4(p);
                    }
                    break;
                }

                case CoordinateSpace.Local:
                {
                    foreach (var index in mesh.selectedCoincidentVertices)
                    {
                        positions[index] += offset;
                    }
                    break;
                }

                case CoordinateSpace.Element:
                {
                    foreach (var elements in group.elementGroups)
                    {
                        var rotation = Quaternion.Inverse(mesh.transform.rotation) * elements.rotation;
                        var o        = rotation * offset;
                        foreach (var index in elements.indices)
                        {
                            positions[index] += o;
                        }
                    }
                    break;
                }
                }

                mesh.Rebuild();
                mesh.Optimize();
                ProBuilderEditor.Refresh();
            }

            if (ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
            {
                return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedEdgeCount + (MeshSelection.selectedEdgeCount > 1 ? " Edges" : " Edge")));
            }
            if (ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
            {
                return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedFaceCount + (MeshSelection.selectedFaceCount > 1 ? " Faces" : " Face")));
            }
            return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedVertexCount + (MeshSelection.selectedVertexCount > 1 ? " Vertices" : " Vertex")));
        }
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Weld Vertices");

            int weldCount = 0;

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                weldCount += mesh.sharedVerticesInternal.Length;

                if (mesh.selectedIndexesInternal.Length > 1)
                {
                    mesh.ToMesh();

                    var   selectedVertices = mesh.GetCoincidentVertices(mesh.selectedVertices);
                    int[] welds            = mesh.WeldVertices(mesh.selectedIndexesInternal, m_WeldDistance);
                    res = welds != null ? new ActionResult(ActionResult.Status.Success, "Weld Vertices") : new ActionResult(ActionResult.Status.Failure, "Failed Weld Vertices");

                    if (res)
                    {
                        var newSelection = welds ?? new int[0] {
                        };

                        if (MeshValidation.ContainsDegenerateTriangles(mesh))
                        {
                            List <int> removedIndices = new List <int>();
                            var        vertexCount    = mesh.vertexCount;

                            if (MeshValidation.RemoveDegenerateTriangles(mesh, removedIndices))
                            {
                                if (removedIndices.Count < vertexCount)
                                {
                                    var newlySelectedVertices = new List <int>();
                                    selectedVertices.Sort();
                                    removedIndices.Sort();

                                    int count = 0;

                                    for (int i = 0; i < selectedVertices.Count; i++)
                                    {
                                        if (count >= removedIndices.Count || selectedVertices[i] != removedIndices[count])
                                        {
                                            newlySelectedVertices.Add(selectedVertices[i] - UnityEngine.ProBuilder.ArrayUtility.NearestIndexPriorToValue(removedIndices, selectedVertices[i]) - 1);
                                        }
                                        else
                                        {
                                            ++count;
                                        }
                                    }

                                    newSelection = newlySelectedVertices.ToArray();
                                }
                                else
                                {
                                    newSelection = new int[0];
                                }
                            }
                            mesh.ToMesh();
                        }
                        mesh.SetSelectedVertices(newSelection);
                    }

                    mesh.Refresh();
                    mesh.Optimize();
                }

                weldCount -= mesh.sharedVerticesInternal.Length;
            }

            ProBuilderEditor.Refresh();

            if (res && weldCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Weld " + weldCount + (weldCount > 1 ? " Vertices" : " Vertex")));
            }

            return(new ActionResult(ActionResult.Status.Failure, "Nothing to Weld"));
        }
Ejemplo n.º 21
0
        ///Show a Task's field. If task null allow add task. Multiple tasks can be added to form a list.
        public static void TaskFieldMulti(Task task, ITaskSystem ownerSystem, Type baseType, Action <Task> callback)
        {
            //if null simply show an assignment button
            if (task == null)
            {
                ShowCreateTaskSelectionButton(ownerSystem, baseType, callback);
                return;
            }

            //Handle Action/ActionLists so that in GUI level a list is used only when needed
            if (baseType == typeof(ActionTask))
            {
                if (!(task is ActionList))
                {
                    ShowCreateTaskSelectionButton(ownerSystem, baseType, (t) =>
                    {
                        var newList = Task.Create <ActionList>(ownerSystem);
                        UndoUtility.RecordObject(ownerSystem.contextObject, "New Action Task");
                        newList.AddAction((ActionTask)task);
                        newList.AddAction((ActionTask)t);
                        callback(newList);
                    });
                }

                ShowTaskInspectorGUI(task, callback);

                if (task is ActionList)
                {
                    var list = (ActionList)task;
                    if (list.actions.Count == 1)
                    {
                        list.actions[0].isUserEnabled = true;
                        callback(list.actions[0]);
                    }
                }
                return;
            }

            //Handle Condition/ConditionLists so that in GUI level a list is used only when needed
            if (baseType == typeof(ConditionTask))
            {
                if (!(task is ConditionList))
                {
                    ShowCreateTaskSelectionButton(ownerSystem, baseType, (t) =>
                    {
                        var newList = Task.Create <ConditionList>(ownerSystem);
                        UndoUtility.RecordObject(ownerSystem.contextObject, "New Condition Task");
                        newList.AddCondition((ConditionTask)task);
                        newList.AddCondition((ConditionTask)t);
                        callback(newList);
                    });
                }

                ShowTaskInspectorGUI(task, callback);

                if (task is ConditionList)
                {
                    var list = (ConditionList)task;
                    if (list.conditions.Count == 1)
                    {
                        list.conditions[0].isUserEnabled = true;
                        callback(list.conditions[0]);
                    }
                }
                return;
            }

            //in all other cases where the base type is not a base ActionTask or ConditionTask,
            //(thus lists can't be used unless the base type IS a list), simple show the inspector.
            ShowTaskInspectorGUI(task, callback);
        }
Ejemplo n.º 22
0
        ///----------------------------------------------------------------------------------------------

#if UNITY_EDITOR
        //Shows blackboard variables mapping
        public static void ShowVariablesMappingGUI(this IGraphAssignable assignable)
        {
            if (assignable.subGraph == null || !assignable.subGraph.allowBlackboardOverrides)
            {
                assignable.variablesMap = null;
                return;
            }

            ParadoxNotion.Design.EditorUtils.Separator();
            ParadoxNotion.Design.EditorUtils.CoolLabel("SubGraph Variables Mapping");

            var subTreeVariables = assignable.subGraph.blackboard.variables.Values;

            if (subTreeVariables.Count == 0 || !subTreeVariables.Any(v => v.isExposedPublic))
            {
                UnityEditor.EditorGUILayout.HelpBox("SubGraph has no exposed public variables. You can make variables exposed public through the 'gear' menu of a variable.", UnityEditor.MessageType.Info);
                assignable.variablesMap = null;
                return;
            }

            UnityEditor.EditorGUILayout.HelpBox("Map SubGraph exposed variables to this graph variables.\nUse the arrow buttons on the right of each parameter to enable WriteIn and/or ReadOut. WriteIn takes place when the SubGraph starts. ReadOut takes place continously while the SubGraph is running.", UnityEditor.MessageType.Info);

            foreach (var variable in subTreeVariables)
            {
                if (variable is Variable <VariableSeperator> )
                {
                    continue;
                }
                if (!variable.isExposedPublic || variable.isPropertyBound)
                {
                    continue;
                }

                if (assignable.variablesMap == null)
                {
                    assignable.variablesMap = new System.Collections.Generic.List <BBMappingParameter>();
                }

                var bbParam = assignable.variablesMap.Find(x => x.targetSubGraphVariableID == variable.ID);
                if (bbParam == null)
                {
                    GUILayout.BeginHorizontal();
                    GUI.enabled = false;
                    EditorUtils.DrawEditorFieldDirect(new GUIContent(variable.name), variable.value, variable.varType, default(InspectedFieldInfo));
                    GUI.enabled = true;
                    int tmp = 0;
                    if (GUILayout.Button(EditorUtils.GetTempContent("▽", null, "Write (In)"), Styles.centerLabel, GUILayout.Width(12)))
                    {
                        tmp = 1;
                    }
                    UnityEditor.EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), UnityEditor.MouseCursor.Link);
                    if (GUILayout.Button(EditorUtils.GetTempContent("△", null, "Read (Out)"), Styles.centerLabel, GUILayout.Width(12)))
                    {
                        tmp = -1;
                    }
                    if (tmp != 0)
                    {
                        UndoUtility.RecordObject(assignable.graph, "Override Variable");
                        bbParam               = new BBMappingParameter(variable);
                        bbParam.canWrite      = tmp == 1;
                        bbParam.canRead       = tmp == -1;
                        bbParam.useBlackboard = tmp == -1;
                        bbParam.value         = variable.value;
                        bbParam.bb            = assignable.graph.blackboard;
                        assignable.variablesMap.Add(bbParam);
                        UndoUtility.SetDirty(assignable.graph);
                    }
                    UnityEditor.EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), UnityEditor.MouseCursor.Link);
                    GUILayout.EndHorizontal();
                    continue;
                }

                if (bbParam.varType != variable.varType && (bbParam.canRead || bbParam.canWrite))
                {
                    bbParam.SetType(variable.varType);
                }

                GUILayout.BeginHorizontal();

                GUI.enabled = bbParam.canRead || bbParam.canWrite;
                NodeCanvas.Editor.BBParameterEditor.ParameterField(variable.name, bbParam);
                if (bbParam.canRead && !bbParam.useBlackboard)
                {
                    EditorUtils.MarkLastFieldWarning("The parameter is set to Read Out, but is not linked to any Variable.");
                }
                GUI.enabled = true;

                if (GUILayout.Button(EditorUtils.GetTempContent(bbParam.canWrite ? "▼" : "▽", null, "Write (In)"), Styles.centerLabel, GUILayout.Width(12)))
                {
                    UndoUtility.RecordObject(assignable.graph, "Set Write In");
                    bbParam.canWrite = !bbParam.canWrite;
                    UndoUtility.SetDirty(assignable.graph);
                }
                UnityEditor.EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), UnityEditor.MouseCursor.Link);
                if (GUILayout.Button(EditorUtils.GetTempContent(bbParam.canRead ? "▲" : "△", null, "Read (Out)"), Styles.centerLabel, GUILayout.Width(12)))
                {
                    UndoUtility.RecordObject(assignable.graph, "Set Read Out");
                    bbParam.canRead = !bbParam.canRead;
                    UndoUtility.SetDirty(assignable.graph);
                }
                UnityEditor.EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), UnityEditor.MouseCursor.Link);
                if (!bbParam.canRead && !bbParam.canWrite)
                {
                    UndoUtility.RecordObject(assignable.graph, "Remove Override");
                    assignable.variablesMap.Remove(bbParam);
                    UndoUtility.SetDirty(assignable.graph);
                }

                GUILayout.EndHorizontal();
            }

            if (assignable.variablesMap != null)
            {
                for (var i = assignable.variablesMap.Count; i-- > 0;)
                {
                    var bbParam  = assignable.variablesMap[i];
                    var variable = assignable.subGraph.blackboard.GetVariableByID(bbParam.targetSubGraphVariableID);
                    if (variable == null || !variable.isExposedPublic || variable.isPropertyBound)
                    {
                        assignable.variablesMap.RemoveAt(i);
                        UndoUtility.SetDirty(assignable.graph);
                    }
                }
            }
        }
        //static because it's also used from DialogueTreeController
        public static void ShowActorParameters(DialogueTree dialogue)
        {
            EditorUtils.CoolLabel("Dialogue Actor Parameters");
            EditorGUILayout.HelpBox("Enter the Key-Value pair for Dialogue Actors involved in the Dialogue.\nThe reference Object must be an IDialogueActor or have an IDialogueActor component. Referencing a Dialogue Actor is optional.", MessageType.Info);

            GUILayout.BeginVertical(GUI.skin.box);

            if (GUILayout.Button("Add Actor Parameter"))
            {
                UndoUtility.RecordObject(dialogue, "New Actor Parameter");
                dialogue.actorParameters.Add(new DialogueTree.ActorParameter("actor parameter name"));
                UndoUtility.SetDirty(dialogue);
            }

            EditorGUILayout.LabelField("INSTIGATOR --> Replaced by the Actor starting the Dialogue");

            var options = new EditorUtils.ReorderableListOptions();

            options.allowAdd           = false;
            options.allowRemove        = true;
            options.unityObjectContext = dialogue;
            EditorUtils.ReorderableList(dialogue.actorParameters, options, (i, picked) =>
            {
                var reference = dialogue.actorParameters[i];
                GUILayout.BeginHorizontal();
                if (dialogue.actorParameters.Where(r => r != reference).Select(r => r.name).Contains(reference.name))
                {
                    GUI.backgroundColor = Color.red;
                }
                var newRefName = EditorGUILayout.DelayedTextField(reference.name);
                if (newRefName != reference.name)
                {
                    UndoUtility.RecordObject(dialogue, "Actor Parameter Name Change");
                    reference.name = newRefName;
                    UndoUtility.SetDirty(dialogue);
                }
                GUI.backgroundColor = Color.white;
                var newReference    = (Object)EditorGUILayout.ObjectField(reference.actor as Object, typeof(Object), true);
                if (!ReferenceEquals(newReference, reference.actor))
                {
                    UndoUtility.RecordObject(dialogue, "Actor Assignment");
                    //all this jazz because ObjectField does not work with interfaces...
                    if (newReference == null)
                    {
                        reference.actor = null;
                    }
                    else
                    {
                        if (newReference is Component)
                        {
                            newReference = (newReference as Component).GetComponent(typeof(IDialogueActor));
                        }
                        if (newReference is GameObject)
                        {
                            newReference = (newReference as GameObject).GetComponent(typeof(IDialogueActor));
                        }
                        if (newReference is IDialogueActor)
                        {
                            reference.actor = (IDialogueActor)newReference;
                        }
                        else
                        {
                            ParadoxNotion.Services.Logger.LogWarning("Object is not an IDialogueActor and none of the components attached is an IDialogueActor either.");
                        }
                    }
                    UndoUtility.SetDirty(dialogue);
                }
                GUILayout.EndHorizontal();
            });

            GUILayout.EndVertical();
        }
 //Bind graph to owner
 public void AssetToBound()
 {
     UndoUtility.RecordObject(owner, "Bind Asset Graph");
     owner.SetBoundGraphReference(owner.graph);
     UndoUtility.SetDirty(owner);
 }
        //...
        void DoValidGraphControls()
        {
            //Graph comments ONLY if Bound graph else readonly
            if (owner.graph != null)
            {
                if (owner.graphIsBound)
                {
                    GUI.contentColor     = Color.white.WithAlpha(0.6f);
                    owner.graph.comments = GUILayout.TextArea(owner.graph.comments, GUILayout.Height(45));
                    GUI.contentColor     = Color.white;
                    EditorUtils.CommentLastTextField(owner.graph.comments, "Graph comments...");
                }
                else
                {
                    GUI.enabled = false;
                    GUILayout.TextArea(owner.graph.comments, GUILayout.Height(45));
                    GUI.enabled = true;
                }
            }

            if (!isBoundGraphOnPrefabRoot)
            {
                //Open behaviour
                GUI.backgroundColor = Colors.lightBlue;
                if (GUILayout.Button(("Edit " + owner.graphType.Name.SplitCamelCase()).ToUpper()))
                {
                    GraphEditor.OpenWindow(owner);
                }
                GUI.backgroundColor = Color.white;
            }
            else
            {
                EditorGUILayout.HelpBox("Bound Graphs on prefabs can only be edited by opening the prefab in the prefab editor.", MessageType.Info);

                //Open prefab and behaviour
                GUI.backgroundColor = Colors.lightBlue;
                if (GUILayout.Button(("Open Prefab And Edit " + owner.graphType.Name.SplitCamelCase()).ToUpper()))
                {
                    AssetDatabase.OpenAsset(owner);
                    GraphEditor.OpenWindow(owner);
                }
                GUI.backgroundColor = Color.white;
            }

            //bind asset or delete bound graph
            if (!Application.isPlaying)
            {
                if (!owner.graphIsBound)
                {
                    if (GUILayout.Button("Bind Graph"))
                    {
                        if (EditorUtility.DisplayDialog("Bind Graph", "This will make a local copy of the graph, bound to the owner.\n\nThis allows you to make local changes and assign scene object references directly.\n\nNote that you can also use scene object references through the use of Blackboard Variables.\n\nBind Graph?", "YES", "NO"))
                        {
                            AssetToBound();
                        }
                    }
                }
                else
                {
                    if (GUILayout.Button("Delete Bound Graph"))
                    {
                        if (EditorUtility.DisplayDialog("Delete Bound Graph", "Are you sure?", "YES", "NO"))
                        {
                            Object.DestroyImmediate(owner.graph, true);
                            UndoUtility.RecordObject(owner, "Delete Bound Graph");
                            owner.SetBoundGraphReference(null);
                            UndoUtility.SetDirty(owner);
                        }
                    }
                }
            }
        }
        //...
        void DoExposedVariablesMapping()
        {
            if (owner.graph == null)
            {
                return;
            }

            var separatorDrawn   = false;
            var subTreeVariables = owner.graph.blackboard.variables.Values;

            foreach (var variable in subTreeVariables)
            {
                if (variable is Variable <VariableSeperator> )
                {
                    continue;
                }
                if (!variable.isExposedPublic || variable.isPropertyBound)
                {
                    continue;
                }

                if (!separatorDrawn)
                {
                    separatorDrawn = true;
                    EditorUtils.Separator();
                    EditorGUILayout.HelpBox("Exposed Graph Variables. Use the arrows button to override/parametrize the variable.\nDoing this will not change the graph serialization. Prefab overrides are also supported.", MessageType.None);
                }

                if (owner.exposedParameters == null)
                {
                    owner.exposedParameters = new System.Collections.Generic.List <ExposedParameter>();
                }
                var exposedParam = owner.exposedParameters.Find(x => x.targetVariableID == variable.ID);
                if (exposedParam == null)
                {
                    GUILayout.BeginHorizontal();
                    GUI.enabled = false;
                    EditorUtils.DrawEditorFieldDirect(new GUIContent(variable.name, "This is an Exposed Public variable of the graph local blackboard. You can use the arrows button on the right side to override/parametrize the default value."), variable.value, variable.varType, default(InspectedFieldInfo));
                    GUI.enabled = true;
                    if (GUILayout.Button(EditorUtils.GetTempContent("▽△", null, "Override Variable"), Styles.centerLabel, GUILayout.Width(24)))
                    {
                        UndoUtility.RecordObject(owner, "Add Override");
                        exposedParam = ExposedParameter.CreateInstance(variable);
                        owner.exposedParameters.Add(exposedParam);
                        exposedParam.Bind(owner.graph.blackboard);
                        UndoUtility.SetDirty(owner);
                    }
                    EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link);
                    GUILayout.EndHorizontal();
                    continue;
                }

                GUILayout.BeginHorizontal();
                var info = new InspectedFieldInfo();
                info.unityObjectContext = owner;
                exposedParam.valueBoxed = EditorUtils.DrawEditorFieldDirect(new GUIContent(variable.name), exposedParam.valueBoxed, variable.varType, info);
                if (GUILayout.Button(EditorUtils.GetTempContent("▼▲", null, "Remove Override"), Styles.centerLabel, GUILayout.Width(24)))
                {
                    UndoUtility.RecordObject(owner, "Remove Override");
                    exposedParam.UnBind(owner.graph.blackboard);
                    owner.exposedParameters.Remove(exposedParam);
                    UndoUtility.SetDirty(owner);
                    continue;
                }
                EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link);
                GUILayout.EndHorizontal();

                var index            = owner.exposedParameters.IndexOf(exposedParam);
                var serProp          = exposeParamsProp.GetArrayElementAtIndex(index);
                var isPrefabOverride = serProp.prefabOverride;
                if (isPrefabOverride)
                {
                    var rect = GUILayoutUtility.GetLastRect();
                    EditorUtils.MarkLastFieldOverride();
                    if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.ContextClick)
                    {
                        var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(owner);
                        var asset           = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabAssetPath);
                        var menu            = new GenericMenu();
                        menu.AddItem(new GUIContent($"Apply to Prefab '{asset.name}'"), false, () =>
                        {
                            UndoUtility.RecordObject(owner, "Apply Exposed Parameter");
                            UndoUtility.RecordObject(asset, "Apply Exposed Parameter");
                            PrefabUtility.ApplyPropertyOverride(serProp, prefabAssetPath, InteractionMode.UserAction);
                            UndoUtility.SetDirty(owner);
                            UndoUtility.SetDirty(asset);
                        });
                        menu.AddItem(new GUIContent("Revert"), false, () =>
                        {
                            UndoUtility.RecordObject(owner, "Revert Exposed Parameter");
                            PrefabUtility.RevertPropertyOverride(serProp, InteractionMode.UserAction);
                            UndoUtility.SetDirty(owner);
                        });
                        menu.ShowAsContext();
                    }
                }
            }

            if (separatorDrawn)
            {
                EditorUtils.Separator();
            }

            //cleanup
            if (owner.exposedParameters != null)
            {
                for (var i = owner.exposedParameters.Count; i-- > 0;)
                {
                    var exposedParam = owner.exposedParameters[i];
                    var variable     = owner.graph.blackboard.GetVariableByID(exposedParam.targetVariableID);
                    if (variable == null || !variable.isExposedPublic || variable.isPropertyBound)
                    {
                        owner.exposedParameters.RemoveAt(i);
                        UndoUtility.SetDirty(owner);
                    }
                }
            }
        }
        ///----------------------------------------------------------------------------------------------

        //EDIT MENU
        static GenericMenu GetToolbarMenu_Edit(Graph graph, GraphOwner owner)
        {
            var menu = new GenericMenu();

            //Bind
            if (!Application.isPlaying && owner != null && !owner.graphIsBound)
            {
                menu.AddItem(new GUIContent("Bind To Owner"), false, () =>
                {
                    if (EditorUtility.DisplayDialog("Bind Graph", "This will make a local copy of the graph, bound to the owner.\n\nThis allows you to make local changes and assign scene object references directly.\n\nNote that you can also use scene object references through the use of Blackboard Variables.\n\nBind Graph?", "YES", "NO"))
                    {
                        UndoUtility.RecordObject(owner, "New Local Graph");
                        owner.SetBoundGraphReference(owner.graph);
                        UndoUtility.SetDirty(owner);
                    }
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Bind To Owner"));
            }

            //Save to asset
            if (!EditorUtility.IsPersistent(graph))
            {
                menu.AddItem(new GUIContent("Save To Asset"), false, () =>
                {
                    var newGraph = (Graph)EditorUtils.CreateAsset(graph.GetType());
                    if (newGraph != null)
                    {
                        EditorUtility.CopySerialized(graph, newGraph);
                        newGraph.Validate();
                        AssetDatabase.SaveAssets();
                    }
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Save To Asset"));
            }

            //Create defined vars
            if (graph.blackboard != null)
            {
                foreach (var bb in graph.blackboard.GetAllParents(true).Reverse())
                {
                    var category = "Promote Missing Parameters To Variables/";
                    menu.AddItem(new GUIContent(category + $"In '{bb.identifier}' Blackboard"), false, () =>
                    {
                        if (EditorUtility.DisplayDialog("Promote Missing Parameters", "This will fill the target Blackboard with a Variable for each defined missing Parameter in the graph.\nContinue?", "YES", "NO"))
                        {
                            UndoUtility.RecordObject(graph, "Promote Variables");
                            UndoUtility.RecordObject(bb.unityContextObject, "Promote Variables");
                            graph.PromoteMissingParametersToVariables(bb);
                            UndoUtility.SetDirty(graph);
                            UndoUtility.SetDirty(bb.unityContextObject);
                        }
                    });
                }
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Promote Defined Parameters To Variables"));
            }

            menu.AddItem(new GUIContent("Scan Graph for Serialized Struct Types"), false, () =>
            {
                GraphEditorUtility.ScanForStructTypesAndAppendThem(graph);
            });

            if (!Application.isPlaying)
            {
                menu.AddItem(new GUIContent("Re-Validate Graph"), false, () =>
                {
                    graph.SelfDeserialize();
                    graph.Validate();
                    FullDrawPass();
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Re-Validate Graph"));
            }

            return(menu);
        }
Ejemplo n.º 28
0
        //Data label (left side)
        void ShowDataLabelGUI(Variable data, int index)
        {
            var e         = Event.current;
            var separator = data.value as VariableSeperator;
            var isVariablePrefabInstanceModified = variablesProperty != null?variablesProperty.GetArrayElementAtIndex(index).prefabOverride : false;

            //this is a separator
            if (separator != null)
            {
                if (!separator.isEditingName)
                {
                    GUI.color = Color.yellow;
                    GUILayout.Label(string.Format("<b>{0}</b>", data.name.ToUpper()), Styles.leftLabel, layoutOptions);
                    GUI.color = Color.white;
                    if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 2 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                    {
                        separator.isEditingName    = true;
                        GUIUtility.keyboardControl = 0;
                        e.Use();
                    }
                }

                if (separator.isEditingName)
                {
                    var newName = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                    if (data.name != newName)
                    {
                        UndoUtility.RecordObject(contextObject, "Separator Rename");
                        data.name = newName;
                        UndoUtility.SetDirty(contextObject);
                    }

                    if ((e.isKey && e.keyCode == KeyCode.Return) || (e.rawType == EventType.MouseUp && !GUILayoutUtility.GetLastRect().Contains(e.mousePosition)))
                    {
                        separator.isEditingName    = false;
                        GUIUtility.keyboardControl = 0;
                        e.Use();
                    }
                }
            }
            else
            {
                //not a separator
                var wasFontStyle = GUI.skin.textField.fontStyle;
                GUI.skin.textField.fontStyle = isVariablePrefabInstanceModified ? FontStyle.Bold : FontStyle.Normal;
                var newName = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                if (data.name != newName)
                {
                    UndoUtility.RecordObject(contextObject, "Variable Name Change");
                    data.name = newName;
                    UndoUtility.SetDirty(contextObject);
                }

                GUI.skin.textField.fontStyle = wasFontStyle;
                EditorGUI.indentLevel        = 0;
            }

            //show a prefab override marker on the left side
            if (isVariablePrefabInstanceModified)
            {
                EditorUtils.MarkLastFieldOverride();
            }
        }
        //...
        static void ParameterDropDown(GUIContent content, BBParameter bbParam)
        {
            if (bbParam.varRef == null && !string.IsNullOrEmpty(bbParam.name))
            {
                bbParam.name        = EditorGUILayout.DelayedTextField(content, bbParam.name);
                GUI.backgroundColor = Color.white.WithAlpha(0.5f);
                if (bbParam.bb != null && GUILayout.Button(EditorUtils.GetTempContent(Icons.plusIcon, "Promote To Variable"), Styles.centerLabel, GUILayout.Width(18), GUILayout.Height(16)))
                {
                    var menu = new GenericMenu();
                    foreach (var bb in bbParam.bb.GetAllParents(true).Reverse())
                    {
                        menu.AddItem(new GUIContent($"Promote Variable in '{bb.identifier}' Blackboard"), false, () =>
                        {
                            UndoUtility.RecordObject(bb.unityContextObject, "Promote Variable");
                            bbParam.PromoteToVariable(bb);
                            UndoUtility.SetDirty(bb.unityContextObject);
                        });
                    }
                    menu.ShowAsContext();
                }
                GUI.backgroundColor = Color.white;
                return;
            }

            GUI.color = new Color(0.9f, 0.9f, 1f, 1f);
            EditorGUILayout.PrefixLabel(content);
            var rect = EditorGUILayout.GetControlRect(false);

            rect.xMin += 2; // O.o
            var cachedContentTextForNew = string.IsNullOrEmpty(content.text) ? string.Format("new{0}", bbParam.varType.Name) : content.text;
            var displayName             = bbParam.isNone ? "[NONE]" : bbParam.name;
            var pop = EditorGUI.DropdownButton(rect, EditorUtils.GetTempContent(displayName), FocusType.Passive);

            GUI.color = Color.white;
            if (pop)
            {
                var menu = new GenericMenu();

                menu.AddItem(new GUIContent("[NONE]"), false, () => { bbParam.name = string.Empty; });

                foreach (var globalBB in GlobalBlackboard.GetAll())
                {
                    var globalVars = globalBB.GetVariables(bbParam.varType);
                    if (globalVars.Count() == 0)
                    {
                        menu.AddDisabledItem(new GUIContent(globalBB.identifier + "/No Assignable Variables"));
                        continue;
                    }
                    foreach (var variable in globalVars)
                    {
                        menu.AddItem(new GUIContent(globalBB.identifier + "/" + variable.name), bbParam.targetVariableID == variable.ID, () => { bbParam.SetTargetVariable(globalBB, variable); });
                    }
                }

                if (bbParam.bb != null)
                {
                    foreach (var actualBB in bbParam.bb.GetAllParents(true).Reverse())
                    {
                        var variables = actualBB.variables.Values.Where(v => v.CanConvertTo(bbParam.varType));
                        if (variables.Count() == 0)
                        {
                            menu.AddDisabledItem(new GUIContent(actualBB.identifier + "/No Assignable Variables"));
                            continue;
                        }
                        foreach (var variable in variables)
                        {
                            menu.AddItem(new GUIContent(actualBB.identifier + "/" + variable.name), bbParam.targetVariableID == variable.ID, () => { bbParam.SetTargetVariable(actualBB, variable); });
                        }
                    }
                }

                menu.AddSeparator(string.Empty);

                if (bbParam.bb != null)
                {
                    foreach (var targetBB in bbParam.bb.GetAllParents(true).Reverse())
                    {
                        menu.AddItem(new GUIContent("(Create New)/In '" + targetBB.identifier + "' Blackboard"), false, () =>
                        {
                            UndoUtility.RecordObject(targetBB.unityContextObject, "New Variable");
                            if (targetBB.AddVariable(cachedContentTextForNew, bbParam.varType) != null)
                            {
                                bbParam.name = cachedContentTextForNew;
                            }
                            else
                            {
                                bbParam.name = null;
                            }
                            UndoUtility.SetDirty(targetBB.unityContextObject);
                        });
                    }
                }

                menu.AddItem(new GUIContent("(DynamicVar)"), false, () => { bbParam.name = "_"; });

                menu.DropDown(rect);
            }
        }
Ejemplo n.º 30
0
        ///<summary>Get a menu for variable</summary>
        GenericMenu GetVariableMenu(Variable data, int index)
        {
            var menu = new GenericMenu();

            if (data.varType == typeof(VariableSeperator))
            {
                menu.AddItem(new GUIContent("Rename"), false, () => { (data.value as VariableSeperator).isEditingName = true; });
                menu.AddItem(new GUIContent("Remove"), false, () =>
                {
                    UndoUtility.RecordObject(contextObject, "Remove Variable");
                    bb.RemoveVariable(data.name);
                    UndoUtility.SetDirty(contextObject);
                });
                return(menu);
            }

            System.Action <PropertyInfo> BindProp = (p) =>
            {
                UndoUtility.RecordObject(contextObject, "Bind Variable");
                data.BindProperty(p);
                UndoUtility.SetDirty(contextObject);
            };
            System.Action <FieldInfo> BindField = (f) =>
            {
                UndoUtility.RecordObject(contextObject, "Bind Variable");
                data.BindProperty(f);
                UndoUtility.SetDirty(contextObject);
            };

            menu.AddDisabledItem(new GUIContent(string.Format("Type: {0}", data.varType.FriendlyName())));

            if (bb.propertiesBindTarget != null)
            {
                foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c != null))
                {
                    menu = EditorUtils.GetInstanceFieldSelectionMenu(comp.GetType(), data.varType, BindField, menu, "Bind (Self)");
                    menu = EditorUtils.GetInstancePropertySelectionMenu(comp.GetType(), data.varType, BindProp, false, false, menu, "Bind (Self)");
                }
                menu.AddSeparator("Bind (Self)/");
            }
            foreach (var type in TypePrefs.GetPreferedTypesList())
            {
                if (bb.propertiesBindTarget != null && typeof(UnityEngine.Component).RTIsAssignableFrom(type))
                {
                    menu = EditorUtils.GetInstanceFieldSelectionMenu(type, typeof(object), BindField, menu, "Bind (Self)");
                    menu = EditorUtils.GetInstancePropertySelectionMenu(type, typeof(object), BindProp, false, false, menu, "Bind (Self)");
                }
                menu = EditorUtils.GetStaticFieldSelectionMenu(type, data.varType, BindField, menu, "Bind (Static)");
                menu = EditorUtils.GetStaticPropertySelectionMenu(type, data.varType, BindProp, false, false, menu, "Bind (Static)");
            }

            menu.AddItem(new GUIContent("Duplicate"), false, () =>
            {
                UndoUtility.RecordObject(contextObject, "Duplicate Variable");
                data.Duplicate(bb);
                UndoUtility.SetDirty(contextObject);
            });

            if (bb is BlackboardSource)     //TODO: avoid this check (but Im too tired now)
            {
                if (!data.isPropertyBound)
                {
                    menu.AddItem(new GUIContent("Exposed Public"), data.isExposedPublic, () =>
                    {
                        UndoUtility.RecordObject(contextObject, "Modify Variable");
                        data.isExposedPublic = !data.isExposedPublic;
                        UndoUtility.SetDirty(contextObject);
                    });
                }
                else
                {
                    menu.AddDisabledItem(new GUIContent("Bound Variables Can't Be Exposed"));
                }
            }

            menu.AddSeparator("/");
            if (data.isPropertyBound)
            {
                menu.AddItem(new GUIContent("Runtime Debug Bound Value"), data.debugBoundValue, () =>
                {
                    UndoUtility.RecordObject(contextObject, "Debug Bound Variable Value");
                    data.debugBoundValue = !data.debugBoundValue;
                    UndoUtility.SetDirty(contextObject);
                });

                menu.AddItem(new GUIContent("UnBind"), false, () =>
                {
                    UndoUtility.RecordObject(contextObject, "UnBind Variable");
                    data.UnBind();
                    UndoUtility.SetDirty(contextObject);
                });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("UnBind"));
            }


            var serProp = variablesProperty?.GetArrayElementAtIndex(index);

            if (serProp != null && serProp.prefabOverride)
            {
                var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(contextObject);
                var asset           = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(prefabAssetPath);
                menu.AddItem(new GUIContent("Apply Prefab Modification To '" + asset.name + "'"), false, () =>
                {
                    UndoUtility.RecordObject(asset, "Apply Variable To Prefab");
                    UndoUtility.RecordObject(contextObject, "Apply Variable To Prefab");
                    PrefabUtility.ApplyPropertyOverride(serProp, prefabAssetPath, InteractionMode.UserAction);
                    UndoUtility.SetDirty(contextObject);
                    UndoUtility.SetDirty(asset);
                });

                menu.AddItem(new GUIContent("Revert Prefab Modification"), false, () =>
                {
                    UndoUtility.RecordObject(contextObject, "Revert Variable From Prefab");
                    PrefabUtility.RevertPropertyOverride(serProp, InteractionMode.UserAction);
                    UndoUtility.SetDirty(contextObject);
                });
            }

            System.Action <System.Type> ChangeType = (t) =>
            {
                UndoUtility.RecordObject(contextObject, "Change Variable Type");
                bb.ChangeVariableType(data, t);
                UndoUtility.SetDirty(contextObject);
            };

            menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), ChangeType, menu, "Change Type");

            menu.AddItem(new GUIContent("Delete Variable"), false, () =>
            {
                if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No"))
                {
                    UndoUtility.RecordObject(contextObject, "Delete Variable");
                    bb.RemoveVariable(data.name);
                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;
                    UndoUtility.SetDirty(contextObject);
                }
            });

            return(menu);
        }