private void SelectBehaviorBrain() { GUIContent content = new GUIContent(BehaviorTreeEditor.active != null ? BehaviorTreeEditor.active.name : "[None Selected]"); float width = EditorStyles.toolbarDropDown.CalcSize(content).x; width = Mathf.Clamp(width, 100f, width); if (GUILayout.Button(content, EditorStyles.toolbarDropDown, GUILayout.Width(width))) { GenericMenu menu = new GenericMenu(); if (BehaviorTreeEditor.active != null) { SelectBehaviorBrainMenu(BehaviorTreeEditor.active, ref menu); } menu.AddItem(new GUIContent("[Craete New]"), false, delegate() { BehaviorTree bt = AssetCreator.CreateAsset <BehaviorTree>(true); if (bt != null) { bt.Name = bt.name; Root root = BehaviorTreeEditorUtility.AddNode <Root>(BehaviorTreeEditor.center, bt); bt.rootNode = root; root.Name = "Root"; AssetDatabase.SaveAssets(); BehaviorTreeEditor.SelectBehaviorTrees(bt); } }); menu.ShowAsContext(); } }
public static T AddService <T>(Composite parent, BehaviorTree bt) { if (parent == null) { Debug.LogWarning("Can't add a service to the behavior trees, because the behavior trees are null."); return(default(T)); } Service service = ScriptableObject.CreateInstance(typeof(T)) as Service; service.hideFlags = HideFlags.HideInHierarchy; service.Name = BehaviorTreeEditorUtility.GenerateName <T>(); service.tick = 0.1f; service.comment = service.Name + ": tick every 0.1s"; service.parent = parent; parent.services = ArrayUtility.Add <Service>(parent.services, service); if (EditorUtility.IsPersistent(bt)) { AssetDatabase.AddObjectToAsset(service, bt); } AssetDatabase.SaveAssets(); return((T)(object)service); }
public static T AddDecorator <T>(Node parent, BehaviorTree bt) { if (parent == null) { Debug.LogWarning("Can't add a decorator to the behavior trees, because the behavior trees are null."); return(default(T)); } Decorator decorator = ScriptableObject.CreateInstance(typeof(T)) as Decorator; decorator.hideFlags = HideFlags.HideInHierarchy; decorator.Name = BehaviorTreeEditorUtility.GenerateName <T>(); decorator.comment = decorator.Name; decorator.parent = parent; parent.decorators = ArrayUtility.Add <Decorator>(parent.decorators, decorator); if (EditorUtility.IsPersistent(bt)) { AssetDatabase.AddObjectToAsset(decorator, bt); } AssetDatabase.SaveAssets(); return((T)(object)decorator); }
public static void DeleteNode(Node node, BehaviorTree bt) { if (node.parentNode != null) { node.parentNode.childNodes = ArrayUtility.Remove <Node>(node.parentNode.childNodes, node); } foreach (Node child in node.childNodes) { child.parentNode = null; } if (node.decorators.Length > 0) { foreach (Decorator decorator in node.decorators) { BehaviorTreeEditorUtility.DeleteDecorator(decorator); } } if (node is Composite && (node as Composite).services.Length > 0) { foreach (Service service in (node as Composite).services) { BehaviorTreeEditorUtility.DeleteService(service); } } bt.nodes = ArrayUtility.Remove <Node>(bt.nodes, node); BehaviorTreeEditorUtility.DestroyImmediate(node); }
protected override void CanvasContextMenu() { if (_currentEvent.type != EventType.MouseDown || _currentEvent.button != 1 || _currentEvent.clickCount != 1 || BehaviorTreeEditor.active == null) { return; } GenericMenu canvasMenu = new GenericMenu(); // Composite canvasMenu.AddItem(new GUIContent("Create Composite/Selector"), false, delegate() { BehaviorTreeEditorUtility.AddNode <Selector>(_mousePosition, BehaviorTreeEditor.active); }); canvasMenu.AddItem(new GUIContent("Create Composite/Sequence"), false, delegate() { BehaviorTreeEditorUtility.AddNode <Sequence>(_mousePosition, BehaviorTreeEditor.active); }); // Task canvasMenu.AddItem(new GUIContent("Create Task/Wait"), false, delegate() { BehaviorTreeEditorUtility.AddNode <Wait>(_mousePosition, BehaviorTreeEditor.active); }); canvasMenu.AddSeparator("Create Task/"); canvasMenu.AddItem(new GUIContent("Create Task/Task"), false, delegate() { BehaviorTreeEditorUtility.AddNode <Task>(_mousePosition, BehaviorTreeEditor.active); }); canvasMenu.ShowAsContext(); }
private static void DrawNode(Node node, bool selected, Texture2D iconImage, int boxColor) { float sharedHeight = node.position.yMin + 15; DrawDecorators(node, ref sharedHeight); Rect insideMainNode = node.position; insideMainNode.xMin += 7; insideMainNode.xMax -= 7; insideMainNode.yMin = sharedHeight; insideMainNode.yMax = sharedHeight + 32 + GetCommentHeight(node.comment); GUIStyle insideMainNodeStyle = BehaviorTreeEditorStyles.GetNodeStyle(boxColor, false); GUI.Box(insideMainNode, "", insideMainNodeStyle); int?myIndex = BehaviorTreeEditorUtility.GetMyIndex(node); if (myIndex != null) { float circleIconWidth = circleIcon.width * 1.1f; float circleIconHeight = circleIcon.height * 1.1f; Rect indexRect = new Rect(insideMainNode.xMax - circleIconWidth / 2f + 12, insideMainNode.yMin - circleIconHeight / 2f, circleIconWidth, circleIconHeight); GUI.DrawTexture(indexRect, circleIcon); indexRect.xMin -= 2; indexRect.yMin -= 2; GUI.Label(indexRect, "<color=white>" + (myIndex + 1).ToString() + "</color>", BehaviorTreeEditorStyles.nodeIndexLabel); } Rect iconRect = node.position; iconRect.x = node.position.xMin + 7; iconRect.y = sharedHeight - 1; GUI.Label(iconRect, iconImage); Rect nameRect = node.position; nameRect.x = node.position.xMin + 42; nameRect.y = sharedHeight + 5; GUI.Label(nameRect, "<color=white>" + node.Name + "</color>", BehaviorTreeEditorStyles.nodeBoxNameNormalStyle); GUIContent commentContent = new GUIContent(node.comment); Rect commentRect = node.position; commentRect.x = node.position.xMin + 7; commentRect.y = sharedHeight + 30; commentRect.width = BehaviorTreeEditorStyles.nodeBoxCommentStyle.CalcSize(commentContent).x + 10; GUI.Label(commentRect, "<color=white>" + node.comment + "</color>", BehaviorTreeEditorStyles.nodeBoxCommentStyle); sharedHeight += insideMainNode.yMax - insideMainNode.yMin + 5; DrawServices(node, sharedHeight); }
public static void BeginInspectorGUI(ref string name, string style = "IN BigTitle", float width = 100f) { GUILayout.BeginVertical(style); EditorGUIUtility.labelWidth = width; if (BehaviorTreeEditorUtility.DrawHeader("Default", false)) { GUILayout.BeginHorizontal(); GUILayout.Space(7f); name = EditorGUILayout.TextField("Name", name); GUILayout.EndHorizontal(); } }
public static void CreateBehaviorTrees() { // This code is borrowed from ICode(https://www.assetstore.unity3d.com/en/#!/content/13761) BehaviorTree bt = AssetCreator.CreateAsset <BehaviorTree>(false); if (bt != null) { bt.Name = bt.name; Root root = BehaviorTreeEditorUtility.AddNode <Root>(BehaviorTreeEditor.center, bt); bt.rootNode = root; root.Name = "Root"; AssetDatabase.SaveAssets(); } }
private void SelectGameObject() { if (GUILayout.Button(BehaviorTreeEditor.activeGameObject != null ? BehaviorTreeEditor.activeGameObject.name : "[None Selected]", EditorStyles.toolbarDropDown, GUILayout.Width(100))) { GenericMenu toolsMenu = new GenericMenu(); List <Brain> brains = BehaviorTreeEditorUtility.FindInScene <Brain>(); foreach (Brain brain in brains) { GameObject gameObject = brain.gameObject; toolsMenu.AddItem(new GUIContent(gameObject.name), false, delegate() { BehaviorTreeEditor.SelectGameObject(gameObject); }); } toolsMenu.ShowAsContext(); } }
public static T AddNode <T>(Vector2 position, BehaviorTree bt) { if (bt == null) { Debug.LogWarning("Can't add a node to the behavior trees, because the behavior trees are null."); return(default(T)); } Node node = ScriptableObject.CreateInstance(typeof(T)) as Node; node.hideFlags = HideFlags.HideInHierarchy; node.Name = BehaviorTreeEditorUtility.GenerateName <T>(); node.comment = node.Name; node.bt = bt; bt.nodes = ArrayUtility.Add <Node>(bt.nodes, node); node.position = new Rect(position.x, position.y, BehaviorTreeEditorStyles.NodeNormalWidth, BehaviorTreeEditorStyles.NodeNormalHeight); if (EditorUtility.IsPersistent(bt)) { AssetDatabase.AddObjectToAsset(node, bt); } if (node is BehaviorTree) { node.position.width = 150f; node.position.height = 45f; Root root = BehaviorTreeEditorUtility.AddNode <Root>(BehaviorTreeEditor.center, node as BehaviorTree); root.Name = "Root"; } else if (node is Wait) { Wait wait = node as Wait; wait.tick = 0.1f; wait.comment = "Wait: 0.1s"; } AssetDatabase.SaveAssets(); return((T)(object)node); }
private void CreateCodePack(System.Type type) { GUILayout.Label("Selected \"" + type.Name + "\"", "LODLevelNotifyText"); GUILayout.Space(6f); List <MethodInfo> decos = GetMethodInfos(type, typeof(bool)); List <MethodInfo> servs = GetMethodInfos(type, typeof(void)); List <MethodInfo> tasks = GetMethodInfos(type, typeof(System.IDisposable)); tasks.AddRange(GetMethodInfos(type, typeof(IEnumerator))); bool created = DrawCreateButton(!(decos.Count > 0) && !(decos.Count > 0) && !(tasks.Count > 0)); if (decos.Count > 0) { if (BehaviorTreeEditorUtility.DrawHeader("Decorators", false)) { DrawMethods(decos); } } if (servs.Count > 0) { if (BehaviorTreeEditorUtility.DrawHeader("Services", false)) { DrawMethods(servs); } } if (tasks.Count > 0) { if (BehaviorTreeEditorUtility.DrawHeader("Tasks", false)) { DrawMethods(tasks); } } if (created) { CreatePrefab(type, "Code Pack"); } }
private void ServiceContextMenu() { if (_currentEvent.type != EventType.MouseDown || _currentEvent.button != 1 || _currentEvent.clickCount != 1) { return; } Service service = MouseOverService(); if (service == null) { return; } int currentIndex = 0; for (int i = 0; i < service.parent.services.Length; i++) { if (service.parent.services[i] == service) { break; } currentIndex++; } GenericMenu menu = new GenericMenu(); if (currentIndex > 0) { menu.AddItem(new GUIContent("Move Up"), false, delegate() { service.parent.services = ArrayUtility.MoveItem <Service>(service.parent.services, currentIndex, currentIndex - 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Up")); } if (currentIndex < service.parent.services.Length - 1) { menu.AddItem(new GUIContent("Move Down"), false, delegate() { service.parent.services = ArrayUtility.MoveItem <Service>(service.parent.services, currentIndex, currentIndex + 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Down")); } menu.AddItem(new GUIContent("Delete Service"), false, delegate() { if (_serviceSelection.Contains(service)) { _serviceSelection.Clear(); } BehaviorTreeEditorUtility.DeleteService(service); UpdateUnitySelection(); EditorUtility.SetDirty(BehaviorTreeEditor.active); }); menu.ShowAsContext(); Event.current.Use(); }
private void DecoratorContextMenu() { if (_currentEvent.type != EventType.MouseDown || _currentEvent.button != 1 || _currentEvent.clickCount != 1) { return; } Decorator decorator = MouseOverDecorator(); if (decorator == null) { return; } int currentIndex = 0; for (int i = 0; i < decorator.parent.decorators.Length; i++) { if (decorator.parent.decorators[i] == decorator) { break; } currentIndex++; } GenericMenu menu = new GenericMenu(); if (currentIndex > 0) { menu.AddItem(new GUIContent("Move Up"), false, delegate() { decorator.parent.decorators = ArrayUtility.MoveItem <Decorator>(decorator.parent.decorators, currentIndex, currentIndex - 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Up")); } if (currentIndex < decorator.parent.decorators.Length - 1) { menu.AddItem(new GUIContent("Move Down"), false, delegate() { decorator.parent.decorators = ArrayUtility.MoveItem <Decorator>(decorator.parent.decorators, currentIndex, currentIndex + 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Down")); } menu.AddItem(new GUIContent("Delete Decorator"), false, delegate() { if (_decoratorSelection.Contains(decorator)) { _decoratorSelection.Clear(); } BehaviorTreeEditorUtility.DeleteDecorator(decorator); UpdateUnitySelection(); EditorUtility.SetDirty(BehaviorTreeEditor.active); }); menu.ShowAsContext(); Event.current.Use(); }
private void NodeContextMenu() { if (_currentEvent.type != EventType.MouseDown || _currentEvent.button != 1 || _currentEvent.clickCount != 1) { return; } Node node = MouseOverNode(); if (node == null) { return; } GenericMenu nodeMenu = new GenericMenu(); if (!(node is Root)) { nodeMenu.AddItem(new GUIContent("Add Decorator/Decorator"), false, delegate() { BehaviorTreeEditorUtility.AddDecorator <Decorator>(node, BehaviorTreeEditor.active); }); if (node is Composite) { nodeMenu.AddItem(new GUIContent("Add Service"), false, delegate() { BehaviorTreeEditorUtility.AddService <Service>((Composite)node, BehaviorTreeEditor.active); }); } else { nodeMenu.AddDisabledItem(new GUIContent("Add Service")); } nodeMenu.AddSeparator("/"); nodeMenu.AddItem(new GUIContent("Delete Node"), false, delegate() { if (_selection.Contains(node)) { foreach (Node mNode in _selection) { if (!(mNode is Root)) { BehaviorTreeEditorUtility.DeleteNode(mNode, BehaviorTreeEditor.active); } } _selection.Clear(); } else { BehaviorTreeEditorUtility.DeleteNode(node, BehaviorTreeEditor.active); } UpdateUnitySelection(); EditorUtility.SetDirty(BehaviorTreeEditor.active); }); } else { nodeMenu.AddDisabledItem(new GUIContent("Add Decorator")); nodeMenu.AddDisabledItem(new GUIContent("Delete Node")); } nodeMenu.ShowAsContext(); Event.current.Use(); }
private static void CheckDecorator(Decorator dc) { if (dc.observerAbortsType == 1 && dc.tick <= 0) { dc.tick = 1; BehaviorTreeEditorUtility.UpdateComment <Decorator>(dc); _isChanged = true; } else if (dc.observerAbortsType != 1 && dc.tick > 0) { dc.tick = 0; BehaviorTreeEditorUtility.UpdateComment <Decorator>(dc); _isChanged = true; } if (dc.targetScript != null && !string.IsNullOrEmpty(dc.targetMethod)) { MethodInfo[] methods = dc.targetScript.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); bool isThereMethod = false; for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(bool)) { continue; } if (method.Name == dc.targetMethod) { isThereMethod = true; break; } } if (!isThereMethod) { dc.Name = "Decorator"; dc.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Decorator>(dc); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(bool)) { continue; } dc.Name = method.Name; dc.targetMethod = method.Name; BehaviorTreeEditorUtility.UpdateComment <Decorator>(dc); break; } _isChanged = true; } } else if (!string.IsNullOrEmpty(dc.targetMethod)) { dc.Name = "Decorator"; dc.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Decorator>(dc); _isChanged = true; } }
private static void CheckTask(Task t) { if (t.childNodes.Length > 0) { t.childNodes = new Node[0]; _isChanged = true; } if (t is Wait) { CheckWaitTask(t as Wait); } else { if (t.targetScript != null && !string.IsNullOrEmpty(t.targetMethod)) { MethodInfo[] methods = t.targetScript.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); bool isThereMethod = false; for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(IEnumerator) && method.ReturnType != typeof(System.IDisposable)) { continue; } if (method.Name == t.targetMethod) { isThereMethod = true; break; } } if (!isThereMethod) { t.Name = "Task"; t.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Task>(t); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(IEnumerator) && method.ReturnType != typeof(System.IDisposable)) { continue; } t.Name = method.Name; t.targetMethod = method.Name; BehaviorTreeEditorUtility.UpdateComment <Task>(t); break; } _isChanged = true; } } else if (!string.IsNullOrEmpty(t.targetMethod)) { t.Name = "Task"; t.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Task>(t); _isChanged = true; } } }
private static void CheckService(Service s) { if (s.tick <= 0) { s.tick = 0.1f; BehaviorTreeEditorUtility.UpdateComment <Service>(s); _isChanged = true; } if (s.targetScript != null && !string.IsNullOrEmpty(s.targetMethod)) { MethodInfo[] methods = s.targetScript.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); bool isThereMethod = false; for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(void)) { continue; } if (method.Name == s.targetMethod) { isThereMethod = true; break; } } if (!isThereMethod) { s.Name = "Service"; s.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Service>(s); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (method.Name == "Initialize") { continue; } if (method.Name.Contains("get_")) { continue; } if (method.ReturnType != typeof(void)) { continue; } s.Name = method.Name; s.targetMethod = method.Name; BehaviorTreeEditorUtility.UpdateComment <Service>(s); break; } _isChanged = true; Debug.Log("Changed at method"); } } else if (!string.IsNullOrEmpty(s.targetMethod)) { s.Name = "Service"; s.targetMethod = ""; BehaviorTreeEditorUtility.UpdateComment <Service>(s); _isChanged = true; } }
public static void DeleteDecorator(Decorator decorator) { decorator.parent.decorators = ArrayUtility.Remove <Decorator>(decorator.parent.decorators, decorator); BehaviorTreeEditorUtility.DestroyImmediate(decorator); }
public static void DeleteService(Service service) { service.parent.services = ArrayUtility.Remove <Service>(service.parent.services, service); BehaviorTreeEditorUtility.DestroyImmediate(service); }