protected override void OnNodeInspectorGUI()
        {
            base.OnNodeInspectorGUI();

            if (GUILayout.Button("Add Parameter"))
            {
                EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), (t) => { AddParameter(t); }).ShowAsContext();
            }

            UnityEditor.EditorGUI.BeginChangeCheck();

            var options = new EditorUtils.ReorderableListOptions();

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

            EditorUtils.Separator();

            EditorUtils.ButtonTypePopup("Return Type", returns.type, (t) => { returns.type = t; GatherPortsUpdateRefs(); });

            if (UnityEditor.EditorGUI.EndChangeCheck())
            {
                GatherPortsUpdateRefs();
            }
        }
Exemple #2
0
        ///----------------------------------------------------------------------------------------------
        ///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
        protected override void OnTaskInspectorGUI()
        {
            var options = new EditorUtils.ReorderableListOptions();

            options.allowAdd           = true;
            options.allowRemove        = true;
            options.unityObjectContext = ownerSystem.contextObject;
            EditorUtils.ReorderableList(statements, options, (i, picked) =>
            {
                if (statements[i] == null)
                {
                    statements[i] = new Statement("...");
                }
                var statement   = statements[i];
                statement.text  = UnityEditor.EditorGUILayout.TextArea(statement.text, (GUIStyle)"textField", GUILayout.Height(50));
                statement.audio = (AudioClip)UnityEditor.EditorGUILayout.ObjectField("Audio Clip", statement.audio, typeof(AudioClip), false);
                statement.meta  = UnityEditor.EditorGUILayout.TextField("Meta", statement.meta);
                EditorUtils.Separator();
            });
        }
        //..
        public override void OnConnectionInspectorGUI(int i)
        {
            var desire   = desires[i];
            var optionsB = new EditorUtils.ReorderableListOptions();

            optionsB.allowAdd    = false;
            optionsB.allowRemove = true;
            EditorUtils.ReorderableList(desire.considerations, optionsB, (j, pickedB) =>
            {
                var consideration = desire.considerations[j];
                GUILayout.BeginVertical("box");
                consideration.input    = (BBParameter <float>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Input", consideration.input, true);
                consideration.function = (BBParameter <AnimationCurve>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Curve", consideration.function);
                GUILayout.EndVertical();
            });

            if (GUILayout.Button("Add Consideration"))
            {
                desire.AddConsideration(graphBlackboard);
            }
            EditorUtils.Separator();
        }
        protected override void OnNodeInspectorGUI()
        {
            if (macro == null)
            {
                return;
            }
            if (GUILayout.Button("Add Flow Input"))
            {
                macro.AddInputDefinition(new DynamicPortDefinition("Flow Input", typeof(Flow)));
            }

            if (GUILayout.Button("Add Value Input"))
            {
                EditorUtils.ShowPreferedTypesSelectionMenu(typeof(object), (t) =>
                {
                    macro.AddInputDefinition(new DynamicPortDefinition(string.Format("{0} Input", t.FriendlyName()), t));
                });
            }

            var options = new EditorUtils.ReorderableListOptions();

            options.allowRemove = true;
            EditorUtils.ReorderableList(macro.inputDefinitions, options, (i, picked) =>
            {
                var def = macro.inputDefinitions[i];
                GUILayout.BeginHorizontal();
                def.name    = UnityEditor.EditorGUILayout.DelayedTextField(def.name, GUILayout.Width(150), GUILayout.ExpandWidth(true));
                GUI.enabled = def.type != typeof(Flow);
                EditorUtils.ButtonTypePopup("", def.type, (t) => { def.type = t; GatherPorts(); });
                GUI.enabled = true;
                GUILayout.EndHorizontal();
            });

            if (GUI.changed)
            {
                GatherPorts();
            }
        }
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            var def = (SignalDefinition)target;

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

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

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

            EditorUtils.EndOfInspector();
            if (Event.current.isMouse)
            {
                Repaint();
            }
        }
        //..
        protected override void OnNodeInspectorGUI()
        {
            if (outConnections.Count == 0)
            {
                GUILayout.Label("Make some connections first");
                return;
            }

            var optionsA = new EditorUtils.ReorderableListOptions();

            optionsA.allowAdd    = false;
            optionsA.allowRemove = false;
            EditorUtils.ReorderableList(desires, optionsA, (i, pickedA) =>
            {
                var desire     = desires[i];
                var desireName = string.IsNullOrEmpty(desire.name) ? "DESIRE " + i.ToString() : desire.name;
                desire.foldout = UnityEditor.EditorGUILayout.Foldout(desire.foldout, new GUIContent(desireName));
                if (desire.foldout)
                {
                    desire.name = UnityEditor.EditorGUILayout.TextField("   Friendly Name", desire.name);
                    OnConnectionInspectorGUI(i);
                }
            });
        }
Exemple #7
0
        ///Show the variables of blackboard serialized in contextParent
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent)
        {
            GUI.skin.label.richText = true;
            var e = Event.current;

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

            //Add variable button
            GUI.backgroundColor = Colors.lightBlue;
            if (GUILayout.Button("Add Variable"))
            {
                GetAddVariableMenu(bb).Show(NCPrefs.useBrowser, "Add Variable");
                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);
            }


            List <Variable> tempList = null;

            if (!tempLists.TryGetValue(bb, out tempList))
            {
                tempList      = bb.variables.Values.ToList();
                tempLists[bb] = tempList;
            }

            if (!tempList.SequenceEqual(bb.variables.Values))
            {
                tempList      = bb.variables.Values.ToList();
                tempLists[bb] = tempList;
            }

            //store the names of the variables being used by current graph selection.
            var usedVariableNames = GraphEditorUtility.activeElement != null?Graph.GetUsedParameterNamesOfTarget(GraphEditorUtility.activeElement) : new List <string>();

            //The actual variables reorderable list
            var options = new EditorUtils.ReorderableListOptions();

            options.CustomItemMenu = (i) => { return(GetVariableMenu(tempList[i], bb)); };
            EditorUtils.ReorderableList(tempList, options, (i, picked) =>
            {
                var data = (Variable)tempList[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                var isUsed = usedVariableNames.Contains(data.name);
                var missingVariableType = data as MissingVariableType;

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

                if (missingVariableType == null)
                {
                    //Name of the variable GUI control
                    if (!Application.isPlaying)
                    {
                        if (picked && data.varType != typeof(VariableSeperator))
                        {
                            pickedVariable           = data;
                            pickedVariableBlackboard = bb;
                        }

                        GUI.color           = Color.white;
                        GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                        //Make name field red if same name exists
                        if (tempList.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.DelayedTextField(data.name, layoutOptions);
                            EditorGUI.indentLevel = 0;
                        }
                        else
                        {
                            var separator = (VariableSeperator)data.value;
                            if (separator == null)
                            {
                                separator = new VariableSeperator();
                            }

                            if (separator.isEditingName)
                            {
                                data.name = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                            }
                            else
                            {
                                GUI.color = Color.yellow;
                                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 highRect   = GUILayoutUtility.GetLastRect();
                        highRect.xMin += 2;
                        highRect.xMax -= 2;
                        highRect.yMax -= 4;
                        GUI.Box(highRect, string.Empty, Styles.highlightBox);
                    }

                    //Show the respective data GUI
                    ShowDataGUI(data, bb, contextParent, layoutOptions);
                }
                else
                {
                    var internalTypeName = missingVariableType.missingType.Split(new string[] { "[[", "]]" }, System.StringSplitOptions.RemoveEmptyEntries)[1];
                    internalTypeName     = internalTypeName.Substring(0, internalTypeName.IndexOf(","));
                    GUILayout.Box(string.Empty, GUILayout.Width(6));
                    GUILayout.Label(data.name, layoutOptions);
                    GUILayout.Label(string.Format("<color=#ff6457>* {0} *</color>", internalTypeName), layoutOptions);
                    if (!Application.isPlaying && GUILayout.Button("x", GUILayout.Width(17), GUILayout.Height(16)))
                    {
                        tempList.Remove(data);
                    }
                }

                //closure
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;
                GUILayout.EndHorizontal();
            }, contextParent);

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

            if (GUI.changed || e.rawType == EventType.MouseUp)
            {
                EditorApplication.delayCall += () => { ResetPick(); };
                //reconstruct the dictionary
                try { bb.variables = tempList.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }
        //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();
        }
        protected override void OnNodeInspectorGUI()
        {
            base.OnNodeInspectorGUI();

            if (GUILayout.Button("Add Parameter"))
            {
                EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), (t) => { AddParameter(t); }).ShowAsContext();
            }

            UnityEditor.EditorGUI.BeginChangeCheck();

            var options = new EditorUtils.ReorderableListOptions();

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

            EditorUtils.Separator();

            EditorUtils.ButtonTypePopup("Return Type", returns.type, (t) => { returns.type = t; GatherPortsUpdateRefs(); });
            if (GUILayout.Button("ResetType"))
            {
                returns.type = null; GatherPortsUpdateRefs();
            }
            if (UnityEditor.EditorGUI.EndChangeCheck())
            {
                GatherPortsUpdateRefs();
            }
            GUILayout.Space(20f);

            if (!reName && GUILayout.Button("Rename"))
            {
                reName       = true;
                renameString = identifier.value;
            }

            if (reName)
            {
                GUILayout.BeginHorizontal();
                renameString = GUILayout.TextField(renameString);
                if (GUILayout.Button("Done"))
                {
                    identifier.value = renameString;
                    callFunctionNodeDict.ForEach(x => x.Value.ForEach(y => y.functionName = identifier.value));
                    reName = false;
                }
                GUILayout.EndHorizontal();
            }

            if (!string.IsNullOrEmpty(identifier.value) && GUILayout.Button("Find Call FunctionNode"))
            {
                FindAllRefNode();
            }

            if (callFunctionNodeDict.Count > 0 || callCustomFunctionNodeDict.Count > 0 || callFunctionSyncNodeDict.Count > 0)
            {
                GUILayout.BeginVertical();
                foreach (var item in callFunctionNodeDict)
                {
                    GUILayout.BeginVertical();
                    GUILayout.Label(item.Key.name);

                    item.Value.ForEach(z => {
                        if (GUILayout.Button(string.Format("callFunctionNode:{0}", z.functionName)))
                        {
                            UnityEditor.Selection.activeObject = item.Key;
                            UnityEditor.Selection.selectionChanged();

                            if (ParadoxNotion.Services.MonoManager.current == null)
                            {
                                var _current = UnityEngine.Object.FindObjectOfType <ParadoxNotion.Services.MonoManager>();
                                if (_current != null)
                                {
                                    UnityEngine.Object.DestroyImmediate(_current.gameObject);
                                }

                                var current = new GameObject("_MonoManager").AddComponent <ParadoxNotion.Services.MonoManager>();
                                current.StartCoroutine(waitForGraphChange(z));
                            }
                            else
                            {
                                ParadoxNotion.Services.MonoManager.current.StartCoroutine(waitForGraphChange(z));
                            }
                        }
                    });

                    GUILayout.EndVertical();
                }

                foreach (var item in callCustomFunctionNodeDict)
                {
                    GUILayout.BeginVertical();
                    GUILayout.Label(item.Key.name);

                    item.Value.ForEach(z => {
                        if (GUILayout.Button(string.Format("callFunctionNode:{0}", z.FunctionName)))
                        {
                            UnityEditor.Selection.activeObject = item.Key;
                            UnityEditor.Selection.selectionChanged();

                            if (ParadoxNotion.Services.MonoManager.current == null)
                            {
                                var _current = UnityEngine.Object.FindObjectOfType <ParadoxNotion.Services.MonoManager>();
                                if (_current != null)
                                {
                                    UnityEngine.Object.DestroyImmediate(_current.gameObject);
                                }

                                var current = new GameObject("_MonoManager").AddComponent <ParadoxNotion.Services.MonoManager>();
                                current.StartCoroutine(waitForGraphChange(z));
                            }
                            else
                            {
                                ParadoxNotion.Services.MonoManager.current.StartCoroutine(waitForGraphChange(z));
                            }

                            NodeCanvas.Editor.GraphEditorUtility.activeElement = z;
                        }
                    });

                    GUILayout.EndVertical();
                }
                foreach (var item in callFunctionSyncNodeDict)
                {
                    GUILayout.BeginVertical();
                    GUILayout.Label(item.Key.name);

                    item.Value.ForEach(z => {
                        if (GUILayout.Button(string.Format("callFunctionNode:{0}", z.FunctionName)))
                        {
                            UnityEditor.Selection.activeObject = item.Key;
                            UnityEditor.Selection.selectionChanged();

                            if (ParadoxNotion.Services.MonoManager.current == null)
                            {
                                var _current = UnityEngine.Object.FindObjectOfType <ParadoxNotion.Services.MonoManager>();
                                if (_current != null)
                                {
                                    UnityEngine.Object.DestroyImmediate(_current.gameObject);
                                }

                                var current = new GameObject("_MonoManager").AddComponent <ParadoxNotion.Services.MonoManager>();
                                current.StartCoroutine(waitForGraphChange(z));
                            }
                            else
                            {
                                ParadoxNotion.Services.MonoManager.current.StartCoroutine(waitForGraphChange(z));
                            }

                            NodeCanvas.Editor.GraphEditorUtility.activeElement = z;
                        }
                    });

                    GUILayout.EndVertical();
                }

                GUILayout.EndVertical();
            }
        }
        ///<summary>Show variables inspector for target bb. Optionally provide override serialization context object</summary>
        void InspectorGUI(IBlackboard bb, UnityEngine.Object overrideContextObject = null)
        {
            if (bb.parent != null)
            {
                ShowVariables(bb.parent);
                EditorUtils.Separator();
            }

            this.contextObject = overrideContextObject != null ? overrideContextObject : bb.unityContextObject;
            this.bb            = bb;

            this.variablesProperty = null;
            if (contextObject != null && PrefabUtility.IsPartOfPrefabInstance(contextObject) && bb.independantVariablesFieldName != null)
            {
                this.serializedContext = new SerializedObject(contextObject);
                this.variablesProperty = serializedContext.FindProperty(bb.independantVariablesFieldName);
            }

            //Add variable button
            GUI.backgroundColor = Colors.lightBlue;
            if (GUILayout.Button("Add Variable"))
            {
                GetAddVariableMenu(bb, contextObject).ShowAsBrowser("Add Variable");
                Event.current.Use();
            }
            GUI.backgroundColor = Color.white;

            //Simple column header info
            EditorGUILayout.HelpBox($"{bb} Blackboard Variables", MessageType.None);
            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();
            }

            //temp list to work with
            if (tempVariablesList == null || !tempVariablesList.SequenceEqual(bb.variables.Values))
            {
                tempVariablesList = bb.variables.Values.ToList();
            }

            //The actual variables reorderable list
            var options = new EditorUtils.ReorderableListOptions();

            options.blockReorder = contextObject != null?PrefabUtility.IsPartOfRegularPrefab(contextObject) : false;

            options.unityObjectContext = contextObject;
            options.customItemMenu     = (i) => { return(GetVariableMenu(tempVariablesList[i], i)); };
            EditorUtils.ReorderableList(tempVariablesList, options, (i, isPicked) =>
            {
                var data = tempVariablesList[i] as Variable;
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!"); return;
                }
                GUILayout.Space(data.varType == typeof(VariableSeperator) ? 5 : 0);
                GUILayout.BeginHorizontal();
                DoVariableGUI(data, i, isPicked);
                GUILayout.EndHorizontal();
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;
                if (elementDefinedParameterIDs != null && elementDefinedParameterIDs.Contains(data.ID))
                {
                    EditorUtils.HighlightLastField();
                }
            });

            //apply temp list reconstruct the dictionary
            if (GUI.changed || Event.current.rawType == EventType.MouseUp)
            {
                EditorApplication.delayCall += () => { ResetPick(); };
                try { bb.variables = tempVariablesList.ToDictionary(d => d.name, d => d); }
                catch { ParadoxNotion.Services.Logger.LogError("Blackboard has duplicate names!", LogTag.EDITOR, bb); }
            }
        }