//Add variable button
        static void DoAddVariableButton(IBlackboard bb, Event e)
        {
            GUI.backgroundColor = EditorUtils.lightBlue;
            if (GUILayout.Button("Add Variable"))
            {
                System.Action <System.Type> AddNewVariable = (t) =>
                {
                    var name = "my" + t.FriendlyName();
                    while (bb.GetVariable(name) != null)
                    {
                        name += ".";
                    }
                    bb.AddVariable(name, t);
                };

                System.Action <PropertyInfo> AddBoundProp = (p) =>
                {
                    var newVar = bb.AddVariable(p.Name, p.PropertyType);
                    newVar.BindProperty(p);
                };

                System.Action <FieldInfo> AddBoundField = (f) =>
                {
                    var newVar = bb.AddVariable(f.Name, f.FieldType);
                    newVar.BindProperty(f);
                };

                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.GetPropertySelectionMenu(comp.GetType(), typeof(object), AddBoundProp, false, false, menu, "Bound (Self)/Property");
                        menu = EditorUtils.GetFieldSelectionMenu(comp.GetType(), typeof(object), AddBoundField, menu, "Bound (Self)/Field");
                    }
                }

                foreach (var type in UserTypePrefs.GetPreferedTypesList(typeof(object)))
                {
                    menu = EditorUtils.GetStaticPropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Static)/Property");
                    menu = EditorUtils.GetStaticFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Static)/Field");
                }


                menu.AddSeparator("/");
                menu.AddItem(new GUIContent("Add Header Separator"), false, () => { bb.AddVariable("Separator (Double Click To Rename)", new VariableSeperator()); });

                menu.ShowAsContext();
                e.Use();
            }
            GUI.backgroundColor = Color.white;
        }
Beispiel #2
0
        ///Return get add variable menu
        static GenericMenu GetAddVariableMenu(IBlackboard bb, UnityEngine.Object contextParent)
        {
            System.Action <System.Type> AddNewVariable = (t) =>
            {
                Undo.RecordObject(contextParent, "Variable Added");
                var name = "my" + t.FriendlyName();
                while (bb.GetVariable(name) != null)
                {
                    name += ".";
                }
                bb.AddVariable(name, t);
            };

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

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

            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)");
                }
            }

            foreach (var type in TypePrefs.GetPreferedTypesList(typeof(object)))
            {
                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, () => { bb.AddVariable("Separator (Double Click To Rename)", new VariableSeperator()); });
            return(menu);
        }
Beispiel #3
0
        ///Get a generic menu per variable
        static GenericMenu GetVariableMenu(Variable data, IBlackboard bb)
        {
            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, () => { bb.RemoveVariable(data.name); });
                return(menu);
            }

            System.Action <PropertyInfo> SelectProp  = (p) => { data.BindProperty(p); };
            System.Action <FieldInfo>    SelectField = (f) => { data.BindProperty(f); };

            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.hideFlags != HideFlags.HideInInspector))
                {
                    menu = EditorUtils.GetInstanceFieldSelectionMenu(comp.GetType(), data.varType, SelectField, menu, "Bind (Self)");
                    menu = EditorUtils.GetInstancePropertySelectionMenu(comp.GetType(), data.varType, SelectProp, false, false, menu, "Bind (Self)");
                }
            }

            foreach (var type in TypePrefs.GetPreferedTypesList())
            {
                menu = EditorUtils.GetStaticFieldSelectionMenu(type, data.varType, SelectField, menu, "Bind (Static)");
                menu = EditorUtils.GetStaticPropertySelectionMenu(type, data.varType, SelectProp, false, false, menu, "Bind (Static)");
            }

            menu.AddItem(new GUIContent("Duplicate"), false, () =>
            {
                var dup   = bb.AddVariable(data.name + '.', data.varType);
                dup.value = data.value;
            });

            menu.AddItem(new GUIContent("Protected"), data.isProtected, () => { data.isProtected = !data.isProtected; });

            menu.AddSeparator("/");
            if (data.hasBinding)
            {
                menu.AddItem(new GUIContent("UnBind"), false, () => { data.UnBindProperty(); });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("UnBind"));
            }

            menu.AddItem(new GUIContent("Delete Variable"), false, () =>
            {
                if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No"))
                {
                    bb.RemoveVariable(data.name);
                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;
                }
            });
            return(menu);
        }
Beispiel #4
0
        ///----------------------------------------------------------------------------------------------

        ///Adds a new Variable<T> with provided value and returns it.
        public static Variable <T> AddVariable <T>(this IBlackboard blackboard, string varName, T value)
        {
            var variable = blackboard.AddVariable <T>(varName);

            variable.value = value;
            return(variable);
        }
Beispiel #5
0
        ///Promotes the parameter to a variable on the target blackboard (overriden if parameter name is a path to a global bb).
        public Variable PromoteToVariable(IBlackboard targetBB)
        {
            if (string.IsNullOrEmpty(name))
            {
                varRef = null;
                return(null);
            }

            var varName = name;
            var bbName  = targetBB != null? targetBB.name : string.Empty;

            if (name.Contains("/"))
            {
                var split = name.Split('/');
                bbName   = split[0];
                varName  = split[1];
                targetBB = GlobalBlackboard.Find(bbName);
            }

            if (targetBB == null)
            {
                varRef = null;
                Debug.LogError(string.Format("Parameter '{0}' failed to promote to a variable, because Blackboard named '{1}' could not be found.", varName, bbName));
                return(null);
            }

            varRef = targetBB.AddVariable(varName, varType);
            Debug.Log(string.Format("Parameter '{0}' (of type '{1}') promoted to a Variable in Blackboard '{2}'.", varName, varType.FriendlyName(), bbName));
            return(varRef);
        }
Beispiel #6
0
 ///Utility function to copy all defined variables of this graph into the provided blackboard
 public void CreateDefinedParameterVariables(IBlackboard bb)
 {
     foreach (var bbParam in GetDefinedParameters())
     {
         bbParam.varRef = bb.AddVariable(bbParam.name, bbParam.varType);
     }
 }
    // helper methods

    public static void Merge(this IBlackboard board1, IBlackboard board2)
    {
        foreach (var var2 in board2.variables)
        {
            if (!board1.variables.ContainsKey(var2.Key))
            {
                // Debug.Log("Adding: " + val.dataName + " " + val.objectValue);
                board1.AddVariable(var2.Key, var2.Value.varType);
                board1.SetValue(var2.Key, var2.Value.value);
            }
        }
    }
Beispiel #8
0
        ///Adds a new Variable in the blackboard
        public static Variable AddVariable(this IBlackboard blackboard, string varName, object value)
        {
            if (value == null)
            {
                Logger.LogError("You can't use AddVariable with a null value. Use AddVariable(string, Type) to add the new variable first", LogTag.BLACKBOARD, blackboard);
                return(null);
            }

            var newVariable = blackboard.AddVariable(varName, value.GetType());

            if (newVariable != null)
            {
                newVariable.value = value;
            }

            return(newVariable);
        }
Beispiel #9
0
        public static void UpdateVariable<T>(this IBlackboard blackboard, string nameVar, T newValue)
        {
            if (blackboard == null || nameVar == null)
            {
                return;
            }

            var v = blackboard.GetVariable<T>(nameVar);

            if (v != null)
            {
                v.SetValue(newValue);
            }
            else
            {
                blackboard.AddVariable<T>(nameVar, newValue);
            }
        }
        ///Duplicate this Variable into target Blackboard
        public Variable Duplicate(IBlackboard targetBB)
        {
            var finalName = this.name;

            while (targetBB.variables.ContainsKey(finalName))
            {
                finalName += ".";
            }
            var newVar = targetBB.AddVariable(finalName, varType);

            if (newVar != null)
            {
                newVar.value           = this.value;
                newVar.propertyPath    = this.propertyPath;
                newVar.isExposedPublic = this.isExposedPublic;
            }
            return(newVar);
        }
Beispiel #11
0
        ///Set the value of the Variable variable defined by its name. If a data by that name and type doesnt exist, a new data is added by that name
        public static Variable SetVariableValue(this IBlackboard blackboard, string varName, object value)
        {
            Variable variable;

            if (!blackboard.variables.TryGetValue(varName, out variable))
            {
                Logger.Log(string.Format("No Variable of name '{0}' and type '{1}' exists on Blackboard '{2}'. Adding new instead...", varName, value != null ? value.GetType().FriendlyName() : "null", blackboard), LogTag.BLACKBOARD, blackboard);
                variable = blackboard.AddVariable(varName, value);
                return(variable);
            }

            try { variable.value = value; }
            catch {
                Logger.LogError(string.Format("Can't cast value '{0}' to blackboard variable of name '{1}' and type '{2}'", value != null ? value.ToString() : "null", varName, variable.varType.FriendlyName()), LogTag.BLACKBOARD, blackboard);
                return(null);
            }

            return(variable);
        }
        ///Promotes the parameter to a variable on the target blackboard (overriden if parameter name is a path to a global bb).
        public Variable PromoteToVariable(IBlackboard targetBB)
        {
            if (string.IsNullOrEmpty(name))
            {
                varRef = null;
                return(null);
            }

            var varName = name;
            var bbName  = targetBB != null? targetBB.name : string.Empty;

            if (name.Contains("/"))
            {
                var split = name.Split('/');
                bbName   = split[0];
                varName  = split[1];
                targetBB = GlobalBlackboard.Find(bbName);
            }

            if (targetBB == null)
            {
                varRef = null;
                Logger.LogError(string.Format("Parameter '{0}' failed to promote to a variable, because Blackboard named '{1}' could not be found.", varName, bbName), "Variable", this);
                return(null);
            }

            varRef = targetBB.AddVariable(varName, varType);
            if (varRef != null)
            {
                                #if UNITY_EDITOR
                if (NodeCanvas.Editor.NCPrefs.logDynamicParametersInfo)
                {
                    Logger.Log(string.Format("Parameter '{0}' (of type '{1}') promoted to a Variable in Blackboard '{2}'.", varName, varType.FriendlyName(), bbName), "Variable", this);
                }
                                #endif
            }
            else
            {
                Logger.LogError(string.Format("Parameter {0} (of type '{1}') failed to promote to a Variable in Blackboard '{2}'.", varName, varType.FriendlyName(), bbName), "Variable", this);
            }
            return(varRef);
        }
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent = null)
        {
            //Assumption
            if (contextParent == null)
                contextParent = bb as UnityEngine.Object;

            var layoutOptions = new GUILayoutOption[]{GUILayout.MaxWidth(100), GUILayout.ExpandWidth(true)};

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = new Color(0.8f,0.8f,1);
            if (GUILayout.Button("Add Variable")){
                System.Action<System.Type> SelectVar = (t)=>
                {
                    var name = "my" + t.FriendlyName();
                    while (bb.GetVariable(name) != null)
                        name += ".";
                    bb.AddVariable(name, t);
                };

                System.Action<System.Reflection.PropertyInfo> SelectBound = (p) =>
                {
                    var newVar = bb.AddVariable(p.Name, p.PropertyType);
                    newVar.BindProperty(p);
                };

                var menu = new GenericMenu();
                menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), SelectVar, true, menu, "New");

                if (bb.propertiesBindTarget != null){
                    foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags == 0) ){
                        menu = EditorUtils.GetPropertySelectionMenu(comp.GetType(), typeof(object), SelectBound, false, false, menu, "Property Bound");
                    }
                }

                menu.ShowAsContext();
                Event.current.Use();
            }

            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0){
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            } else {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }

            if (!tempStates.ContainsKey(bb))
                tempStates.Add(bb, new ReorderingState(bb.variables.Values.ToList()));

            //Make temporary list for editing variables
            if (!tempStates[bb].isReordering)
                tempStates[bb].list = bb.variables.Values.ToList();

            //The actual variables reorderable list
            EditorUtils.ReorderableList(tempStates[bb].list, delegate(int i){

                var data = tempStates[bb].list[i];
                if (data == null){
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                GUILayout.BeginHorizontal();

                //Name of the variable GUI control
                if (!Application.isPlaying){

                    //The small box on the left to re-order variables
                    GUI.backgroundColor = new Color(1,1,1,0.8f);
                    GUILayout.Box("", GUILayout.Width(6));
                    GUI.backgroundColor = new Color(0.7f,0.7f,0.7f, 0.3f);

                    if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) )
                        tempStates[bb].isReordering = true;

                    //Make name field red if same name exists
                    if (tempStates[bb].list.Where(v => v != data).Select(v => v.name).Contains(data.name))
                        GUI.backgroundColor = Color.red;
                    GUI.enabled = !data.nonEditable;
                    data.name = EditorGUILayout.TextField(data.name, layoutOptions);
                    GUI.enabled = true;
                    GUI.backgroundColor = Color.white;

                } else {

                    //Don't allow name edits in play mode. Instead show just a label
                    GUI.backgroundColor = new Color(0.7f,0.7f,0.7f);
                    GUI.color = new Color(0.8f,0.8f,1f);
                    GUILayout.Label(data.name, layoutOptions);
                }

                //reset coloring
                GUI.color = Color.white;
                GUI.backgroundColor = Color.white;

                //Show the respective data GUI
                ShowDataGUI(data, bb, contextParent, layoutOptions);

                //reset coloring
                GUI.color = Color.white;
                GUI.backgroundColor = Color.white;

                //'X' to delete data
                if (GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(16))){
                    if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No!")){
                        tempStates[bb].list.Remove(data);
                    }
                }

                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color = Color.white;

            if ( (GUI.changed && !tempStates[bb].isReordering) || Event.current.type == EventType.MouseUp){
                tempStates[bb].isReordering = false;
                //reconstruct the dictionary
                try { bb.variables = tempStates[bb].list.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }
 public void AddOrUpdate(string name, Object value)
 {
     board.AddVariable(name, value);
 }
Beispiel #15
0
 ///Adds a new Variable<T> with default T value and returns it
 public static Variable <T> AddVariable <T>(this IBlackboard blackboard, string varName)
 {
     return((Variable <T>)blackboard.AddVariable(varName, typeof(T)));
 }
Beispiel #16
0
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent)
        {
            var layoutOptions = new GUILayoutOption[] { GUILayout.MaxWidth(100), GUILayout.ExpandWidth(true), GUILayout.Height(16) };

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = new Color(0.8f, 0.8f, 1);
            if (GUILayout.Button("Add Variable"))
            {
                System.Action <System.Type> SelectVar = (t) =>
                {
                    var name = "my" + t.FriendlyName();
                    while (bb.GetVariable(name) != null)
                    {
                        name += ".";
                    }
                    bb.AddVariable(name, t);
                };

                System.Action <PropertyInfo> SelectBoundProp = (p) =>
                {
                    var newVar = bb.AddVariable(p.Name, p.PropertyType);
                    newVar.BindProperty(p);
                };

                System.Action <FieldInfo> SelectBoundField = (f) =>
                {
                    var newVar = bb.AddVariable(f.Name, f.FieldType);
                    newVar.BindProperty(f);
                };

                var menu = new GenericMenu();
                menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), SelectVar, true, menu, "New");

                if (bb.propertiesBindTarget != null)
                {
                    foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags == 0))
                    {
                        menu = EditorUtils.GetPropertySelectionMenu(comp.GetType(), typeof(object), SelectBoundProp, false, false, menu, "Bound Property");
                        menu = EditorUtils.GetFieldSelectionMenu(comp.GetType(), typeof(object), SelectBoundField, menu, "Bound Field");
                    }
                }

                menu.AddSeparator("/");
                menu.AddItem(new GUIContent("Separator"), false, () => { SelectVar(typeof(VariableSeperator)); });

                menu.ShowAsContext();
                Event.current.Use();
            }


            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0)
            {
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }

            if (!tempStates.ContainsKey(bb))
            {
                tempStates.Add(bb, new ReorderingState(bb.variables.Values.ToList()));
            }

            //Make temporary list for editing variables
            if (!tempStates[bb].isReordering)
            {
                tempStates[bb].list = bb.variables.Values.ToList();
            }

            //The actual variables reorderable list
            EditorUtils.ReorderableList(tempStates[bb].list, delegate(int i){
                var data = tempStates[bb].list[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                GUILayout.BeginHorizontal();

                //Name of the variable GUI control
                if (!Application.isPlaying)
                {
                    //The small box on the left to re-order variables
                    GUI.backgroundColor = new Color(1, 1, 1, 0.8f);
                    GUILayout.Box("", GUILayout.Width(6));
                    GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                    if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
                    {
                        tempStates[bb].isReordering = true;
                        if (data.varType != typeof(VariableSeperator))
                        {
                            pickedVariable           = data;
                            pickedVariableBlackboard = bb;
                        }
                    }

                    //Make name field red if same name exists
                    if (tempStates[bb].list.Where(v => v != data).Select(v => v.name).Contains(data.name))
                    {
                        GUI.backgroundColor = Color.red;
                    }

                    GUI.enabled = !data.isProtected;
                    if (data.varType != typeof(VariableSeperator))
                    {
                        data.name = EditorGUILayout.TextField(data.name, layoutOptions);
                    }
                    else
                    {
                        GUILayout.Box("------------", layoutOptions);
                    }
                    GUI.enabled         = true;
                    GUI.backgroundColor = Color.white;
                }
                else
                {
                    //Don't allow name edits in play mode. Instead show just a label
                    if (data.varType != typeof(VariableSeperator))
                    {
                        GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                        GUI.color           = new Color(0.8f, 0.8f, 1f);
                        GUILayout.Label(data.name, layoutOptions);
                    }
                    else
                    {
                        GUI.color = Color.black;
                        GUILayout.Box("------------", layoutOptions);
                        GUI.color = Color.white;
                    }
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //Show the respective data GUI
                if (data.varType != typeof(VariableSeperator))
                {
                    ShowDataGUI(data, bb, contextParent, layoutOptions);
                }
                else
                {
                    GUILayout.Space(0);
                    GUILayout.Space(0);
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //'X' to delete data
                if (!Application.isPlaying && GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(16)))
                {
                    if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No!"))
                    {
                        tempStates[bb].list.Remove(data);
                    }
                }

                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color           = Color.white;

            if ((GUI.changed && !tempStates[bb].isReordering) || Event.current.rawType == EventType.MouseUp)
            {
                tempStates[bb].isReordering  = false;
                EditorApplication.delayCall += () => { pickedVariable = null; pickedVariableBlackboard = null; };
                //reconstruct the dictionary
                try { bb.variables = tempStates[bb].list.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent)
        {
            GUI.skin.label.richText = true;
            var e             = Event.current;
            var layoutOptions = new GUILayoutOption[] { GUILayout.MaxWidth(100), GUILayout.ExpandWidth(true), GUILayout.Height(16) };

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = new Color(0.8f, 0.8f, 1);
            if (GUILayout.Button("Add Variable"))
            {
                System.Action <System.Type> SelectVar = (t) =>
                {
                    var name = "my" + t.FriendlyName();
                    while (bb.GetVariable(name) != null)
                    {
                        name += ".";
                    }
                    bb.AddVariable(name, t);
                };

                System.Action <PropertyInfo> SelectBoundProp = (p) =>
                {
                    var newVar = bb.AddVariable(p.Name, p.PropertyType);
                    newVar.BindProperty(p);
                };

                System.Action <FieldInfo> SelectBoundField = (f) =>
                {
                    var newVar = bb.AddVariable(f.Name, f.FieldType);
                    newVar.BindProperty(f);
                };

                var menu = new GenericMenu();
                menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), SelectVar, true, menu, "New");

                if (bb.propertiesBindTarget != null)
                {
                    foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags != HideFlags.HideInInspector))
                    {
                        menu = EditorUtils.GetPropertySelectionMenu(comp.GetType(), typeof(object), SelectBoundProp, false, false, menu, "Bound (Self)/Property");
                        menu = EditorUtils.GetFieldSelectionMenu(comp.GetType(), typeof(object), SelectBoundField, menu, "Bound (Self)/Field");
                    }
                }

                foreach (var type in UserTypePrefs.GetPreferedTypesList(typeof(object), true))
                {
                    menu = EditorUtils.GetStaticPropertySelectionMenu(type, typeof(object), SelectBoundProp, false, false, menu, "Bound (Static)/Property");
                    menu = EditorUtils.GetStaticFieldSelectionMenu(type, typeof(object), SelectBoundField, menu, "Bound (Static)/Field");
                }


                menu.AddSeparator("/");
                menu.AddItem(new GUIContent("Add Header Separator"), false, () => { SelectVar(typeof(VariableSeperator)); });

                menu.ShowAsContext();
                e.Use();
            }


            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0)
            {
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }

            if (!tempStates.ContainsKey(bb))
            {
                tempStates.Add(bb, new ReorderingState(bb.variables.Values.ToList()));
            }

            //Make temporary list for editing variables
            if (!tempStates[bb].isReordering)
            {
                tempStates[bb].list = bb.variables.Values.ToList();
            }

            //store the names of the variables being used by current graph selection.
            var usedVariables = GetUsedVariablesBySelectionParameters();

            //The actual variables reorderable list
            EditorUtils.ReorderableList(tempStates[bb].list, delegate(int i){
                var data = tempStates[bb].list[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                var isUsed = usedVariables.Contains(data.name);

                GUILayout.Space(data.varType == typeof(VariableSeperator)? 5 : 0);

                GUILayout.BeginHorizontal();

                //Name of the variable GUI control
                if (!Application.isPlaying)
                {
                    //The small box on the left to re-order variables
                    GUI.backgroundColor = new Color(1, 1, 1, 0.8f);
                    GUILayout.Box("", GUILayout.Width(6));
                    GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                    if (e.type == EventType.MouseDown && e.button == 0 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                    {
                        tempStates[bb].isReordering = true;
                        if (data.varType != typeof(VariableSeperator))
                        {
                            pickedVariable           = data;
                            pickedVariableBlackboard = bb;
                        }
                    }

                    //Make name field red if same name exists
                    if (tempStates[bb].list.Where(v => v != data).Select(v => v.name).Contains(data.name))
                    {
                        GUI.backgroundColor = Color.red;
                    }

                    GUI.enabled = !data.isProtected;
                    if (data.varType != typeof(VariableSeperator))
                    {
                        data.name             = EditorGUILayout.TextField(data.name, layoutOptions);
                        EditorGUI.indentLevel = 0;
                    }
                    else
                    {
                        var separator = (VariableSeperator)data.value;

                        GUI.color = Color.yellow;
                        if (separator.isEditingName)
                        {
                            data.name = EditorGUILayout.TextField(data.name, layoutOptions);
                        }
                        else
                        {
                            GUILayout.Label(string.Format("<b>{0}</b>", data.name).ToUpper(), layoutOptions);
                        }
                        GUI.color = Color.white;

                        if (!separator.isEditingName)
                        {
                            if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 2 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                            {
                                separator.isEditingName    = true;
                                GUIUtility.keyboardControl = 0;
                            }
                        }

                        if (separator.isEditingName)
                        {
                            if ((e.isKey && e.keyCode == KeyCode.Return) || (e.rawType == EventType.MouseUp && !GUILayoutUtility.GetLastRect().Contains(e.mousePosition)))
                            {
                                separator.isEditingName    = false;
                                GUIUtility.keyboardControl = 0;
                            }
                        }

                        data.value = separator;
                    }

                    GUI.enabled         = true;
                    GUI.backgroundColor = Color.white;
                }
                else
                {
                    //Don't allow name edits in play mode. Instead show just a label
                    if (data.varType != typeof(VariableSeperator))
                    {
                        GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                        GUI.color           = new Color(0.8f, 0.8f, 1f);
                        GUILayout.Label(data.name, layoutOptions);
                    }
                    else
                    {
                        GUI.color = Color.yellow;
                        GUILayout.Label(string.Format("<b>{0}</b>", data.name.ToUpper()), layoutOptions);
                        GUI.color = Color.white;
                    }
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //Highlight used variable by selection?
                if (isUsed)
                {
                    var r   = GUILayoutUtility.GetLastRect();
                    r.xMin += 2;
                    r.xMax -= 2;
                    r.yMax -= 4;
                    GUI.Box(r, "", (GUIStyle)"LightmapEditorSelectedHighlight");
                }

                //Show the respective data GUI
                if (data.varType != typeof(VariableSeperator))
                {
                    ShowDataGUI(data, bb, contextParent, layoutOptions);
                }
                else
                {
                    GUILayout.Space(0);
                    GUILayout.Space(0);
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //'X' to delete data
                if (!Application.isPlaying && GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(16)))
                {
                    if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No!"))
                    {
                        tempStates[bb].list.Remove(data);
                        bb.RemoveVariable(data.name);
                        GUIUtility.hotControl      = 0;
                        GUIUtility.keyboardControl = 0;
                    }
                }

                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color           = Color.white;

            if ((GUI.changed && !tempStates[bb].isReordering) || e.rawType == EventType.MouseUp)
            {
                tempStates[bb].isReordering  = false;
                EditorApplication.delayCall += () => { pickedVariable = null; pickedVariableBlackboard = null; };
                //reconstruct the dictionary
                try { bb.variables = tempStates[bb].list.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }
Beispiel #18
0
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent = null)
        {
            //Assumption
            if (contextParent == null)
            {
                contextParent = bb as UnityEngine.Object;
            }

            var layoutOptions = new GUILayoutOption[] { GUILayout.MaxWidth(100), GUILayout.ExpandWidth(true) };

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = new Color(0.8f, 0.8f, 1);
            if (GUILayout.Button("Add Variable"))
            {
                System.Action <System.Type> Select = (t) => { bb.AddVariable("my" + t.FriendlyName(), t); };
                EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), Select).ShowAsContext();
                Event.current.Use();
            }

            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0)
            {
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }

            if (!tempStates.ContainsKey(bb))
            {
                tempStates.Add(bb, new ReorderingState(bb.variables.Values.ToList()));
            }

            //Make temporary list for editing variables
            if (!tempStates[bb].isReordering)
            {
                tempStates[bb].list = bb.variables.Values.ToList();
            }

            //The actual variables reorderable list
            EditorUtils.ReorderableList(tempStates[bb].list, delegate(int i){
                var data = tempStates[bb].list[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                GUILayout.BeginHorizontal();

                //Name of the variable GUI control
                if (!Application.isPlaying)
                {
                    //The small box on the left to re-order variables
                    GUI.backgroundColor = new Color(1, 1, 1, 0.8f);
                    GUILayout.Box("", GUILayout.Width(6));
                    GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                    if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
                    {
                        tempStates[bb].isReordering = true;
                    }

                    //Make name field red if same name exists
                    if (tempStates[bb].list.Where(v => v != data).Select(v => v.name).Contains(data.name))
                    {
                        GUI.backgroundColor = Color.red;
                    }
                    data.name           = EditorGUILayout.TextField(data.name, layoutOptions);
                    GUI.backgroundColor = Color.white;
                }
                else
                {
                    //Don't allow name edits in play mode. Instead show just a label
                    GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                    GUI.color           = new Color(0.8f, 0.8f, 1f);
                    GUILayout.Label(data.name, layoutOptions);
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //Show the respective data GUI
                ShowDataGUI(data, bb, contextParent, layoutOptions);

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                //'X' to delete data
                if (GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(16)))
                {
                    if (EditorUtility.DisplayDialog("Delete Variable '" + data.name + "'", "Are you sure?", "Yes", "No!"))
                    {
                        tempStates[bb].list.Remove(data);
                    }
                }

                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color           = Color.white;

            if ((GUI.changed && !tempStates[bb].isReordering) || Event.current.type == EventType.MouseUp)
            {
                tempStates[bb].isReordering = false;
                //reconstruct the dictionary
                try { bb.variables = tempStates[bb].list.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }