void AddContextField(BehaviourTreeExecutionNode node, PropertyReader.Variable variable) { GUILayout.BeginHorizontal(); try { if (!node.contextLink.ContainsKey(variable.name)) { node.contextLink[variable.name] = variable.name.Split('_')[1]; } string initialValue = node.contextLink[variable.name]; GUI.color = Color.black; GUILayout.Label(variable.name.Split('_')[1], GUI.skin.label); GUI.color = Color.white; string value = EditorGUILayout.TextField(initialValue); node.contextLink[variable.name] = value; if (value != initialValue) { BehaviourTreeEditorWindow.SaveNodeAnChildren(node); } } catch (KeyNotFoundException e) { Debug.LogError("the key " + variable.name + " is not in the task context link array."); Debug.LogException(e); } GUILayout.EndHorizontal(); }
public static bool OnOpenAsset(int instanceID, int line) { BehaviourTree behaviourTree = Selection.activeObject as BehaviourTree; if (behaviourTree != null) { Instance = EditorWindow.GetWindow <BehaviourTreeEditorWindow>("BehaviourTree"); Instance.InitEditor(behaviourTree); Instance.selectedNode = BehaviourTreeEditorWindow.behaviourTree; return(true); //catch open file } return(false); // let unity open the file }
void SubTreeWindowFunction(int windowID) { BehaviourTreeSubTreeNode node = (BehaviourTreeSubTreeNode)FindNodeByID(BehaviourTreeEditorWindow.behaviourTree, windowID); Event current = Event.current; if (current.mousePosition.x >= 0.0f && current.mousePosition.x <= nodeSize.x * zoomScale && current.mousePosition.y >= 0.0f && current.mousePosition.y <= nodeSize.y * zoomScale && DragAndDrop.objectReferences.Length == 1) { Object subTreeScriptAsset = DragAndDrop.objectReferences[0]; if (!(subTreeScriptAsset is MonoScript)) { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } else { DragAndDrop.visualMode = DragAndDropVisualMode.Link; } } if (current.type == EventType.MouseDown && current.button == 1) { this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } GenericMenu menu = new GenericMenu(); AddInsertNewParentOptions(menu); AddMoveOption(menu); menu.AddItem(new GUIContent("Delete Node"), false, DeleteNodeCallback); menu.ShowAsContext(); current.Use(); } else if (current.type.Equals(EventType.DragExited)) { Object subTreeScriptAsset = DragAndDrop.objectReferences[0]; if (!(subTreeScriptAsset is MonoScript)) { Debug.Log("not a MonoScript"); current.Use(); return; } System.Type subTreeType = (subTreeScriptAsset as MonoScript).GetClass(); ScriptableObject so = ScriptableObject.CreateInstance(subTreeType); if (!(so is BehaviourTree)) { Debug.Log("not a BehaviourTree"); current.Use(); return; } node.subTree = so as BehaviourTree; node.displayedName = subTreeType.ToString(); BehaviourTreeEditorWindow.SaveBehaviourTree(); this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } current.Use(); } else if (current.type == EventType.MouseDown && current.button == 0 && current.clickCount == 2) { Selection.activeObject = node.subTree; OnOpenAsset(0, 0); current.Use(); } else if (current.type == EventType.MouseDown && current.button == 0) { this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } current.Use(); } }
void ExecutionWindowFunction(int windowID) { BehaviourTreeExecutionNode node = (BehaviourTreeExecutionNode)FindNodeByID(BehaviourTreeEditorWindow.behaviourTree, windowID); Event current = Event.current; if (current.mousePosition.x >= 0.0f && current.mousePosition.x <= nodeSize.x * zoomScale && current.mousePosition.y >= 0.0f && current.mousePosition.y <= nodeSize.y * zoomScale && DragAndDrop.objectReferences.Length == 1) { Object taskScriptAsset = DragAndDrop.objectReferences[0]; if (!(taskScriptAsset is MonoScript)) { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } else { DragAndDrop.visualMode = DragAndDropVisualMode.Link; } } if (current.type == EventType.MouseDown && current.button == 1) { this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } GenericMenu menu = new GenericMenu(); AddInsertNewParentOptions(menu); AddMoveOption(menu); menu.AddItem(new GUIContent("Delete Node"), false, DeleteNodeCallback); menu.ShowAsContext(); current.Use(); } else if (current.type.Equals(EventType.DragExited)) { Object taskScriptAsset = DragAndDrop.objectReferences[0]; if (!(taskScriptAsset is MonoScript)) { current.Use(); return; } System.Type taskType = (taskScriptAsset as MonoScript).GetClass(); ScriptableObject so = ScriptableObject.CreateInstance(taskType); if (!(so is BehaviourTreeTask)) { current.Use(); return; } BehaviourTreeTask oldTaskToRemove = node.task; node.task = so as BehaviourTreeTask; node.contextLink.Clear(); PropertyReader.Variable[] variables = PropertyReader.GetFields(node.task.GetType()); foreach (PropertyReader.Variable variable in variables) { if (variable.name.StartsWith("in_") || variable.name.StartsWith("out_")) { node.contextLink.Add(variable.name, variable.name.Split('_')[1]); } } node.displayedName = taskType.ToString(); AddTaskToAssets(node, oldTaskToRemove); BehaviourTreeEditorWindow.SaveBehaviourTree(); this.selectedNode = node; Selection.activeObject = taskScriptAsset; SelectNodeButDontChangeProjectView(); current.Use(); } else if (current.type == EventType.MouseDown && current.button == 0 && current.clickCount == 2) { this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } MonoScript monoscript = MonoScript.FromScriptableObject(node.task); string scriptPath = AssetDatabase.GetAssetPath(monoscript); UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(scriptPath, 0); current.Use(); } else if (current.type == EventType.MouseDown && current.button == 0) { this.selectedNode = node; if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree) { SelectNodeButDontChangeProjectView(); } current.Use(); } }
public void OnEnable() { Instance = EditorWindow.GetWindow <BehaviourTreeEditorWindow>("BehaviourTree"); InitEditor(behaviourTreeSerializedSaved); }
public static void ShowWindow() { Instance = GetWindow <BehaviourTreeEditorWindow>(false, "BehaviourTree", true); Instance.InitEditor(null); }
void AddParameterField(BehaviourTreeExecutionNode node, PropertyReader.Variable variable) { GUILayout.BeginHorizontal(); object initialValue = PropertyReader.GetValue(node.task, variable.name); GUI.color = Color.black; GUILayout.Label(variable.name.Split('_')[1], GUI.skin.label); GUI.color = Color.white; object value = null; if (variable.type == typeof(string)) { value = EditorGUILayout.TextField((string)initialValue); } else if (variable.type == typeof(float)) { value = EditorGUILayout.FloatField((float)initialValue); } else if (variable.type == typeof(int)) { value = EditorGUILayout.IntField((int)initialValue); } else if (variable.type == typeof(double)) { value = EditorGUILayout.DoubleField((double)initialValue); } else if (variable.type == typeof(bool)) { value = EditorGUILayout.Toggle((bool)initialValue); } if (value == null) { GUILayout.EndHorizontal(); return; } if (value != initialValue) { SerializedObject taskSerializedAsset = new SerializedObject(node.task); taskSerializedAsset.Update(); PropertyReader.SetValue(node.task, variable.name, value); SerializedProperty p = taskSerializedAsset.FindProperty(variable.name); if (value is string) { p.stringValue = (string)value; } else if (value is float) { p.floatValue = (float)value; } else if (value is int) { p.intValue = (int)value; } else if (value is double) { p.doubleValue = (double)value; } else if (value is bool) { p.boolValue = (bool)value; } taskSerializedAsset.ApplyModifiedProperties(); BehaviourTreeEditorWindow.SaveNodeAnChildren(node); } GUILayout.EndHorizontal(); }
public override void OnInspectorGUI() { Repaint(); GUIStyle titleStyle = new GUIStyle(); titleStyle.fontSize = 20; GUIStyle partStyle = new GUIStyle(); partStyle.fontSize = 15; if (BehaviourTreeEditorWindow.Instance == null) { return; } BehaviourTreeNode selectedNode = BehaviourTreeEditorWindow.Instance.selectedNode; if (selectedNode == null) { return; } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(selectedNode.displayedName, titleStyle); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(30); if (selectedNode is BehaviourTreeControlNode) { BehaviourTreeControlNode node = (BehaviourTreeControlNode)selectedNode; GUI.color = Color.white; BehaviourTreeControlNode.Type initialTypeValue = node.type; BehaviourTreeControlNode.Type typeValue = (BehaviourTreeControlNode.Type)EditorGUILayout.EnumPopup("Type", initialTypeValue); if (typeValue != initialTypeValue) { node.type = typeValue; node.displayedName = typeValue.ToString().Replace('_', ' '); BehaviourTreeEditorWindow.SaveNodeAnChildren(node); BehaviourTreeEditorWindow.Instance.Repaint(); } if (node.type != BehaviourTreeControlNode.Type.PARALLEL) { bool initialMemorizeValue = node.startFromFirstNodeEachTick; GUILayout.Space(5); GUILayout.BeginHorizontal(); GUI.color = Color.black; GUILayout.Label("Don't memorize running node", GUI.skin.label); GUI.color = Color.white; bool memorizeValue = EditorGUILayout.Toggle(initialMemorizeValue); if (memorizeValue != initialMemorizeValue) { node.startFromFirstNodeEachTick = memorizeValue; BehaviourTreeEditorWindow.SaveNodeAnChildren(node); BehaviourTreeEditorWindow.Instance.Repaint(); } GUILayout.EndHorizontal(); } } else if (selectedNode is BehaviourTreeExecutionNode) { BehaviourTreeExecutionNode node = (BehaviourTreeExecutionNode)selectedNode; if (node.task != null) { // GUILayout.Space(nodeSize.y * zoomScale); PropertyReader.Variable[] variables = PropertyReader.GetFields(node.task.GetType()); GUILayout.Label("PARAMETER", partStyle); foreach (PropertyReader.Variable variable in variables) { if (variable.name.StartsWith("param_")) { GUILayout.Space(5); AddParameterField(node, variable); } } GUILayout.Space(20); GUILayout.Label("INPUT", partStyle); foreach (PropertyReader.Variable variable in variables) { if (variable.name.StartsWith("in_")) { GUILayout.Space(5); AddContextField(node, variable); } } GUILayout.Space(20); GUILayout.Label("OUTPUT", partStyle); foreach (PropertyReader.Variable variable in variables) { if (variable.name.StartsWith("out_")) { GUILayout.Space(5); AddContextField(node, variable); } } } } else if (selectedNode is BehaviourTreeDecoratorNode) { BehaviourTreeDecoratorNode node = (BehaviourTreeDecoratorNode)selectedNode; GUI.color = Color.white; BehaviourTreeDecoratorNode.Type initialTypeValue = node.type; BehaviourTreeDecoratorNode.Type typeValue = (BehaviourTreeDecoratorNode.Type)EditorGUILayout.EnumPopup("Type", initialTypeValue); if (typeValue != initialTypeValue) { node.type = typeValue; node.displayedName = typeValue.ToString().Replace('_', ' '); BehaviourTreeEditorWindow.SaveNodeAnChildren(node); BehaviourTreeEditorWindow.Instance.Repaint(); } } else if (selectedNode is BehaviourTreeSubTreeNode) { BehaviourTreeSubTreeNode node = (BehaviourTreeSubTreeNode)selectedNode; GUI.color = Color.white; BehaviourTree initialValue = node.subTree; BehaviourTree newValue = (BehaviourTree)EditorGUILayout.ObjectField(node.subTree, typeof(BehaviourTree), false); if (newValue != initialValue) { node.subTree = newValue; node.displayedName = newValue.ToString().Replace('_', ' ').Split('(')[0]; BehaviourTreeEditorWindow.SaveNodeAnChildren(node); BehaviourTreeEditorWindow.Instance.Repaint(); } } }