示例#1
0
        //Shows a button that when clicked, pops a context menu with a list of tasks deriving the base type specified. When something is selected the callback is called
        //On top of that it also shows a search field for Tasks
        public static void ShowCreateTaskSelectionButton(ITaskSystem ownerSystem, Type baseType, Action <Task> callback)
        {
            GUI.backgroundColor = Colors.lightBlue;
            var label = "Assign " + baseType.Name.SplitCamelCase();

            if (GUILayout.Button(label))
            {
                Action <Type> TaskTypeSelected = (t) =>
                {
                    var newTask = Task.Create(t, ownerSystem);
                    UndoUtility.RecordObject(ownerSystem.contextObject, "New Task");
                    callback(newTask);
                };

                var menu = EditorUtils.GetTypeSelectionMenu(baseType, TaskTypeSelected);
                if (CopyBuffer.TryGetCache <Task>(out Task copy) && baseType.IsAssignableFrom(copy.GetType()))
                {
                    menu.AddSeparator("/");
                    menu.AddItem(new GUIContent(string.Format("Paste ({0})", copy.name)), false, () => { callback(copy.Duplicate(ownerSystem)); });
                }
                menu.ShowAsBrowser(label, typeof(Task));
            }

            GUILayout.Space(2);
            GUI.backgroundColor = Color.white;
        }
        //show variable data
        void ShowDataFieldGUI(Variable data, int index)
        {
            //Prop Bind info
            if (data.isPropertyBound)
            {
                var idx        = data.propertyPath.LastIndexOf('.');
                var typeName   = data.propertyPath.Substring(0, idx);
                var memberName = data.propertyPath.Substring(idx + 1);
                GUI.color = new Color(0.8f, 0.8f, 1);
                var suf = data.debugBoundValue && Application.isPlaying ? data.value.ToStringAdvanced() : typeName.Split('.').Last();
                GUILayout.Label(string.Format(".{0} ({1}) {2}", memberName, suf, data.debugBoundValue ? "*" : string.Empty), Styles.leftLabel, layoutOptions);
                GUI.color = Color.white;
                return;
            }

            GUI.color = data.isExposedPublic ? GUI.color.WithAlpha(0.5f) : GUI.color;
            EditorGUIUtility.labelWidth = 10;
            var newVal = VariableField(data, contextObject, layoutOptions);

            EditorGUIUtility.labelWidth = 0;
            if (!Equals(data.value, newVal))
            {
                UndoUtility.RecordObject(contextObject, "Variable Value Change");
                data.value = newVal;
                UndoUtility.SetDirty(contextObject);
            }
            GUI.color = Color.white;
        }
        ///----------------------------------------------------------------------------------------------

        //...
        public override void OnInspectorGUI()
        {
            DoPrefabRelatedGUI();

            if (owner.graph == null && !owner.graphIsBound)
            {
                DoMissingGraphControls();
                serializedObject.ApplyModifiedProperties();
                return;
            }

            DoValidGraphControls();
            DoStandardFields();

            EditorGUI.BeginChangeCheck();
            GUI.enabled = (!isBoundGraphOnPrefabInstance || !owner.lockBoundGraphPrefabOverrides) && !isBoundGraphOnPrefabRoot;
            OnPreExtraGraphOptions();
            GUI.enabled = true;
            if (EditorGUI.EndChangeCheck() && owner.graph != null)
            {
                UndoUtility.RecordObject(owner.graph, "Sub Option Change");
                owner.graph.SelfSerialize();
                UndoUtility.SetDirty(owner.graph);
            }
            EditorUtils.ReflectedObjectInspector(owner, owner);

            DoExposedVariablesMapping();
            DoRuntimeGraphControls();

            OnPostExtraGraphOptions();
            EditorUtils.EndOfInspector();
            serializedObject.ApplyModifiedProperties();
        }
示例#4
0
        ///----------------------------------------------------------------------------------------------

        ///<summary>Self Serialize blackboard</summary>
        public void SelfSerialize()
        {
            if (haltForUndo || ParadoxNotion.Services.Threader.applicationIsPlaying || Application.isPlaying)
            {
                return;
            }

            var newReferences    = new List <UnityEngine.Object>();
            var newSerialization = JSONSerializer.Serialize(typeof(BlackboardSource), _blackboard, newReferences);

            if (newSerialization != _serializedBlackboard || !newReferences.SequenceEqual(_objectReferences) || (_serializedVariables == null || _serializedVariables.Length != _blackboard.variables.Count))
            {
                haltForUndo = true;
                UndoUtility.RecordObject(this, UndoUtility.GetLastOperationNameOr("Blackboard Change"));
                haltForUndo = false;

                _serializedVariables = new SerializationPair[_blackboard.variables.Count];
                for (var i = 0; i < _blackboard.variables.Count; i++)
                {
                    var serializedVariable = new SerializationPair();
                    serializedVariable._json = JSONSerializer.Serialize(typeof(Variable), _blackboard.variables.ElementAt(i).Value, serializedVariable._references);
                    _serializedVariables[i]  = serializedVariable;
                }

                _serializedBlackboard = newSerialization;
                _objectReferences     = newReferences;
            }
        }
示例#5
0
        ///Generate and return task menu
        GenericMenu GetMenu(Action <Task> callback)
        {
            var menu = new GenericMenu();

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

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

            menu.AddSeparator("/");

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

            return(menu);
        }
        ///Show the sub-tasks list
        public void ShowListGUI()
        {
            if (ownerSystem == null)
            {
                GUILayout.Label("Owner System is null!");
                return;
            }

            TaskEditor.ShowCreateTaskSelectionButton <ActionTask>(ownerSystem, AddAction);

            ValidateList();

            if (actions.Count == 0)
            {
                EditorGUILayout.HelpBox("No Actions", MessageType.None);
                return;
            }

            if (actions.Count == 1)
            {
                return;
            }

            //show the actions
            EditorUtils.ReorderableList(actions, (i, picked) =>
            {
                var action = actions[i];
                GUI.color  = Color.white.WithAlpha(action == currentViewAction ? 0.75f : 0.25f);
                EditorGUILayout.BeginHorizontal("box");

                GUI.color            = Color.white.WithAlpha(action.isUserEnabled ? 0.8f : 0.25f);
                GUI.enabled          = !Application.isPlaying;
                action.isUserEnabled = EditorGUILayout.Toggle(action.isUserEnabled, GUILayout.Width(18));
                GUI.enabled          = true;

                GUILayout.Label((action.isPaused ? "<b>||</b> " : action.isRunning ? "► " : "") + action.summaryInfo, GUILayout.MinWidth(0), GUILayout.ExpandWidth(true));

                if (!Application.isPlaying && GUILayout.Button("X", GUILayout.Width(20)))
                {
                    UndoUtility.RecordObject(ownerSystem.contextObject, "List Remove Task");
                    actions.RemoveAt(i);
                }

                EditorGUILayout.EndHorizontal();

                var lastRect = GUILayoutUtility.GetLastRect();
                EditorGUIUtility.AddCursorRect(lastRect, MouseCursor.Link);
                if (Event.current.type == EventType.MouseDown && lastRect.Contains(Event.current.mousePosition))
                {
                    currentViewAction = action == currentViewAction ? null : action;
                    Event.current.Use();
                }

                GUI.color = Color.white;
            });

            executionMode = (ActionsExecutionMode)EditorGUILayout.EnumPopup(executionMode);
        }
示例#7
0
        ///Duplicate the task for the target ITaskSystem
        virtual public Task Duplicate(ITaskSystem newOwnerSystem)
        {
            var newTask = JSONSerializer.Clone <Task>(this);

            UndoUtility.RecordObject(newOwnerSystem.contextObject, "Duplicate Task");
            BBParameter.SetBBFields(newTask, newOwnerSystem.blackboard);
            newTask.Validate(newOwnerSystem);
            return(newTask);
        }
        //create new local graph and assign it to owner
        public Graph NewAsBound()
        {
            var newGraph = (Graph)ScriptableObject.CreateInstance(owner.graphType);

            UndoUtility.RecordObject(owner, "New Bound Graph");
            owner.SetBoundGraphReference(newGraph);
            UndoUtility.SetDirty(owner);
            return(newGraph);
        }
        //Apply bound graph
        public void PrefabApplyBoundGraph()
        {
            UndoUtility.RecordObject(owner, "Apply Graph To Prefab");
            var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(owner);

            PrefabUtility.ApplyPropertyOverride(boundGraphSerializationProp, prefabAssetPath, InteractionMode.UserAction);
            PrefabUtility.ApplyPropertyOverride(boundGraphReferencesProp, prefabAssetPath, InteractionMode.UserAction);
            UndoUtility.SetDirty(owner);
        }
示例#10
0
        public static Task Create(Type type, ITaskSystem newOwnerSystem)
        {
            var newTask = (Task)Activator.CreateInstance(type);

            UndoUtility.RecordObject(newOwnerSystem.contextObject, "New Task");
            BBParameter.SetBBFields(newTask, newOwnerSystem.blackboard);
            newTask.Validate(newOwnerSystem);
            newTask.OnCreate(newOwnerSystem);
            return(newTask);
        }
示例#11
0
        ///Show the sub-tasks list
        public void ShowListGUI()
        {
            TaskEditor.ShowCreateTaskSelectionButton <ConditionTask>(ownerSystem, AddCondition);

            ValidateList();

            if (conditions.Count == 0)
            {
                EditorGUILayout.HelpBox("No Conditions", MessageType.None);
                return;
            }

            if (conditions.Count == 1)
            {
                return;
            }

            EditorUtils.ReorderableList(conditions, (i, picked) =>
            {
                var condition = conditions[i];
                GUI.color     = Color.white.WithAlpha(condition == currentViewCondition ? 0.75f : 0.25f);
                GUILayout.BeginHorizontal("box");

                GUI.color               = Color.white.WithAlpha(condition.isUserEnabled ? 0.8f : 0.25f);
                GUI.enabled             = !Application.isPlaying;
                condition.isUserEnabled = EditorGUILayout.Toggle(condition.isUserEnabled, GUILayout.Width(18));
                GUI.enabled             = true;

                GUILayout.Label(condition.summaryInfo, GUILayout.MinWidth(0), GUILayout.ExpandWidth(true));

                if (!Application.isPlaying && GUILayout.Button("X", GUILayout.MaxWidth(20)))
                {
                    UndoUtility.RecordObject(ownerSystem.contextObject, "List Remove Task");
                    conditions.RemoveAt(i);
                    if (conditions.Count == 1)
                    {
                        conditions[0].isUserEnabled = true;
                    }
                }

                GUILayout.EndHorizontal();

                var lastRect = GUILayoutUtility.GetLastRect();
                EditorGUIUtility.AddCursorRect(lastRect, MouseCursor.Link);
                if (Event.current.type == EventType.MouseDown && lastRect.Contains(Event.current.mousePosition))
                {
                    currentViewCondition = condition == currentViewCondition ? null : condition;
                    Event.current.Use();
                }

                GUI.color = Color.white;
            });

            checkMode = (ConditionsCheckMode)EditorGUILayout.EnumPopup(checkMode);
        }
        //Revert bound graph
        public void PrefabRevertBoundGraph()
        {
            UndoUtility.RecordObject(owner, "Revert Graph From Prefab");
            var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(owner);

            PrefabUtility.RevertPropertyOverride(boundGraphSerializationProp, InteractionMode.UserAction);
            PrefabUtility.RevertPropertyOverride(boundGraphReferencesProp, InteractionMode.UserAction);
            GraphEditorUtility.activeElement = null;
            UndoUtility.SetDirty(owner);
            GraphEditor.FullDrawPass();
        }
示例#13
0
        //...
        bool DoListCheckout(List <string> options, ref List <string> selected)
        {
            var changed = false;

            //show potential missing first
            for (var i = selected.Count; i-- > 0;)
            {
                var s = selected[i];
                if (!options.Contains(s))
                {
                    GUILayout.BeginHorizontal(GUI.skin.box);
                    GUILayout.Label(s.FormatError());
                    if (GUILayout.Button("Remove", GUILayout.Width(75)))
                    {
                        changed = true;
                        UndoUtility.RecordObject(graph, "Extractor");
                        selected.RemoveAt(i);
                        UndoUtility.SetDirty(graph);
                    }
                    GUILayout.EndHorizontal();
                }
            }

            //show expose options
            for (var i = 0; i < options.Count; i++)
            {
                var name   = options[i];
                var active = selected.Contains(name);
                GUI.color = Color.white.WithAlpha(active ? 1 : 0.5f);
                GUILayout.BeginHorizontal(GUI.skin.box);
                GUILayout.Label(name.SplitCamelCase());
                GUILayout.Label("Expose", GUILayout.Width(50));
                GUI.color = Color.white;
                var newActive = UnityEditor.EditorGUILayout.Toggle(active, GUILayout.Width(20));
                GUILayout.EndHorizontal();
                if (newActive != active)
                {
                    changed = true;
                    UndoUtility.RecordObject(graph, "Extractor");
                    if (newActive == true)
                    {
                        selected.Add(name);
                    }
                    if (newActive == false)
                    {
                        selected.Remove(name);
                    }
                    UndoUtility.SetDirty(graph);
                }
            }
            return(changed);
        }
        //create new graph asset and assign it to owner
        public Graph NewAsAsset()
        {
            var newGraph = (Graph)EditorUtils.CreateAsset(owner.graphType);

            if (newGraph != null)
            {
                UndoUtility.RecordObject(owner, "New Asset Graph");
                owner.graph = newGraph;
                UndoUtility.SetDirty(owner);
                UndoUtility.SetDirty(newGraph);
                AssetDatabase.SaveAssets();
            }
            return(newGraph);
        }
示例#15
0
        public static Task Create(Type type, ITaskSystem newOwnerSystem)
        {
            if (type.IsGenericTypeDefinition)
            {
                type = type.MakeGenericType(type.GetFirstGenericParameterConstraintType());
            }
            var newTask = (Task)Activator.CreateInstance(type);

            UndoUtility.RecordObject(newOwnerSystem.contextObject, "New Task");
            BBParameter.SetBBFields(newTask, newOwnerSystem.blackboard);
            newTask.Validate(newOwnerSystem);
            newTask.OnCreate(newOwnerSystem);
            return(newTask);
        }
示例#16
0
        //Shows the agent field in case an agent type is specified through the use of the generic versions of Action or Condition Task
        void ShowAgentField()
        {
            if (task.agentType == null)
            {
                return;
            }

            TaskAgentParameter agentParam = agentParameterProp.value;

            if (Application.isPlaying && task.agentIsOverride && agentParam.value == null)
            {
                GUILayout.Label("<b>Missing Agent Reference</b>".FormatError());
                return;
            }

            GUI.color = Color.white.WithAlpha(task.agentIsOverride ? 0.65f : 0.5f);
            GUILayout.BeginVertical(GUI.skin.box);
            GUILayout.BeginHorizontal();

            if (task.agentIsOverride)
            {
                BBParameterEditor.ParameterField(null, agentParam, task.ownerSystem.contextObject);
            }
            else
            {
                var compInfo = task.agent == null?task.agentType.FriendlyName().FormatError() : task.agentType.FriendlyName();

                var icon    = TypePrefs.GetTypeIcon(task.agentType);
                var label   = string.Format("Use Self ({0})", compInfo);
                var content = EditorUtils.GetTempContent(label, icon);
                GUILayout.Label(content, GUILayout.Height(18), GUILayout.Width(0), GUILayout.ExpandWidth(true));
            }

            GUI.color = Color.white;

            if (!Application.isPlaying)
            {
                var newOverride = EditorGUILayout.Toggle(task.agentIsOverride, GUILayout.Width(18));
                if (newOverride != task.agentIsOverride)
                {
                    UndoUtility.RecordObject(task.ownerSystem.contextObject, "Override Agent");
                    task.agentIsOverride = newOverride;
                }
            }

            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }
示例#17
0
        public void AddAction(ActionTask action)
        {
            if (action is ActionList)
            {
                foreach (var subAction in (action as ActionList).actions)
                {
                    AddAction(subAction);
                }
                return;
            }

#if UNITY_EDITOR
            UndoUtility.RecordObject(ownerSystem.contextObject, "List Add Task");
            currentViewAction = action;
#endif

            actions.Add(action);
            action.SetOwnerSystem(this.ownerSystem);
        }
示例#18
0
        public void AddCondition(ConditionTask condition)
        {
            if (condition is ConditionList)
            {
                foreach (var subCondition in (condition as ConditionList).conditions)
                {
                    AddCondition(subCondition);
                }
                return;
            }

#if UNITY_EDITOR
            UndoUtility.RecordObject(ownerSystem.contextObject, "List Add Task");
            currentViewCondition = condition;
#endif

            conditions.Add(condition);
            condition.SetOwnerSystem(this.ownerSystem);
        }
示例#19
0
        ///Create a new Node of type and assigned to the provided graph. Use this for constructor
        public static Node Create(Graph targetGraph, System.Type nodeType, Vector2 pos)
        {
            if (targetGraph == null)
            {
                Logger.LogError("Can't Create a Node without providing a Target Graph", LogTag.GRAPH);
                return(null);
            }

            var newNode = (Node)System.Activator.CreateInstance(nodeType);

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

            newNode.graph    = targetGraph;
            newNode.position = pos;
            BBParameter.SetBBFields(newNode, targetGraph.blackboard);
            newNode.Validate(targetGraph);
            newNode.OnCreate(targetGraph);
            UndoUtility.SetDirty(targetGraph);
            return(newNode);
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 2)
            {
                return(new ActionResult(ActionResult.Status.Canceled, "Must Select 2+ Objects"));
            }

            var            selected    = MeshSelection.top.ToArray();
            ProBuilderMesh currentMesh = MeshSelection.activeMesh;

            UndoUtility.RecordObject(currentMesh, "Merge Objects");
            List <ProBuilderMesh> res = CombineMeshes.Combine(MeshSelection.topInternal, currentMesh);

            if (res != null)
            {
                foreach (var mesh in res)
                {
                    mesh.Optimize();
                    if (mesh != currentMesh)
                    {
                        mesh.gameObject.name = Selection.activeGameObject.name + "-Merged";
                        UndoUtility.RegisterCreatedObjectUndo(mesh.gameObject, "Merge Objects");
                        Selection.objects = res.Select(x => x.gameObject).ToArray();
                    }
                }

                // Delete donor objects if they are not part of the result
                for (int i = 0; i < selected.Length; i++)
                {
                    if (selected[i] != null && res.Contains(selected[i]) == false)
                    {
                        UndoUtility.DestroyImmediate(selected[i].gameObject);
                    }
                }
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Merged Objects"));
        }
示例#21
0
        /**
         *  \brief Duplicates and mirrors the passed pb_Object.
         *  @param pb The donor pb_Object.
         *  @param axe The axis to mirror the object on.
         *  \returns The newly duplicated pb_Object.
         *  \sa ProBuilder.Axis
         */
        public static ProBuilderMesh Mirror(ProBuilderMesh pb, Vector3 scale, bool duplicate = true)
        {
            ProBuilderMesh mirredObject;

            if (duplicate)
            {
                mirredObject = Object.Instantiate(pb.gameObject, pb.transform.parent, false).GetComponent <ProBuilderMesh>();
                mirredObject.MakeUnique();
                mirredObject.transform.parent        = pb.transform.parent;
                mirredObject.transform.localRotation = pb.transform.localRotation;
                Undo.RegisterCreatedObjectUndo(mirredObject.gameObject, "Mirror Object");
            }
            else
            {
                UndoUtility.RecordObject(pb, "Mirror");
                mirredObject = pb;
            }

            Vector3 lScale = mirredObject.gameObject.transform.localScale;

            mirredObject.transform.localScale = scale;

            // if flipping on an odd number of axes, flip winding order
            if ((scale.x * scale.y * scale.z) < 0)
            {
                foreach (var face in mirredObject.facesInternal)
                {
                    face.Reverse();
                }
            }

            mirredObject.FreezeScaleTransform();
            mirredObject.transform.localScale = lScale;

            mirredObject.ToMesh();
            mirredObject.Refresh();
            mirredObject.Optimize();

            return(mirredObject);
        }
示例#22
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);
        }
示例#23
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);
        }
示例#24
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);
        }
示例#25
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);
        }
示例#26
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);
        }
        //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();
        }
示例#28
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 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);
            }
        }
示例#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);
        }