public BehaviorTreeView(EditorDomain domain, BehaviorTreeState tree, Vector2 windowSize) : base(domain, null, string.Format("{0}-View", tree.Id)) { Tree = tree; Size = windowSize; scrollOffset = new Vector2(windowSize.x / 2, EditorConfiguration.NodeSize.y); Children.Add(new BehaviorTreeNode(domain, this)); NodeLayoutHelper.Calculate(Tree); }
public BehaviorTreeNode(EditorDomain domain, BehaviorTreeView parent) : base(domain , parent , string.Format("{0}-Node", parent.Tree.Id)) { Tree = parent.Tree; Tree.OnEventApplied += Tree_OnEventApplied; if (Tree.RootTaskId > 0) { var task = (TaskState)Repository.States[TaskState.GetId(Tree.RootTaskId)]; RootView.Children.Add(TaskNode.Create(RootView, task)); } }
public static void Calculate(BehaviorTreeState tree) { if (tree.RootTaskId == 0) { return; } var root = CreateTaskLayoutInfos(tree, tree.RootTaskId); root.Task.Position = new Vector2(EditorConfiguration.BehaviorTreeNodePosition.x, EditorConfiguration.BehaviorTreeNodePosition.y + EditorConfiguration.TaskNodeMinSpace.y + EditorConfiguration.NodeSize.y / 2 + EditorConfiguration.NodeSize.y / 2); CalculateTaskPosition(root); }
public void Deserialize() { if (Domain != null) { return; } var repo = new EditorRepository(); var handler = new BehaviorTreeCommandHandler(); var domain = new EditorDomain(repo, handler); domain.OnEventApplied += Domain_OnEventApplied; var treeId = BehaviorTreeState.GetId(); var tree = new BehaviorTreeState(domain, treeId); tree.Asset = this; repo.States[treeId] = tree; if (bytes != null && bytes.Length > 0) { var treeDesc = BehaviorTreeSerializer.DeserializeDesc(bytes); tree.Title = treeDesc.Title; tree.Comment = treeDesc.Comment; tree.RootTaskId = treeDesc.RootTaskId; if (treeDesc.Tasks != null && treeDesc.Tasks.Length > 0) { tree.NextTaskId = treeDesc.Tasks.Max(t => t.Id) + 1; foreach (var taskDesc in treeDesc.Tasks) { var taskId = TaskState.GetId(taskDesc.Id); var task = new TaskState(domain, taskId); if (taskDesc.Id != treeDesc.RootTaskId) { task.ParentTaskId = EditorHelper.FindParentTask(treeDesc.Tasks, taskDesc.Id).Id; } task.Desc = taskDesc; repo.States[task.Id] = task; } } } Domain = domain; Tree = tree; }
private void OnTaskCreatedEvent(TaskCreatedEvent e) { Repository.States[e.NewTask.Id] = e.NewTask; if (Desc is DecoratorTaskDescWrapper) { var desc = (DecoratorTaskDescWrapper)Desc; desc.ChildTaskId = e.NewTask.Desc.Id; } else if (Desc is CompositeTaskDescWrapper) { var desc = (CompositeTaskDescWrapper)Desc; desc.ChildTaskIds.Add(e.NewTask.Desc.Id); } var tree = (BehaviorTreeState)Repository.States[BehaviorTreeState.GetId()]; tree.NextTaskId = Math.Max(tree.NextTaskId, e.NewTask.Desc.Id) + 1; NodeLayoutHelper.Calculate(tree); }
private static Node CreateTaskLayoutInfos(BehaviorTreeState tree, uint taskId) { var task = (TaskState)tree.Repository.States[TaskState.GetId(taskId)]; var node = new Node() { Task = task }; node.LaneWidth = EditorConfiguration.NodeSize.x + EditorConfiguration.TaskNodeMinSpace.x / 2; if (!node.Task.IsCollapsed) { if (node.Task.Desc is DecoratorTaskDescWrapper) { var childTaskId = ((DecoratorTaskDescWrapper)node.Task.Desc).ChildTaskId; if (childTaskId > 0) { var childTaskInfo = CreateTaskLayoutInfos(tree, childTaskId); node.Children = new[] { childTaskInfo }; node.LaneWidth = childTaskInfo.LaneWidth; } } else if (node.Task.Desc is CompositeTaskDescWrapper) { var childTaskIds = ((CompositeTaskDescWrapper)node.Task.Desc).ChildTaskIds; if (childTaskIds.Count > 0) { node.Children = (childTaskIds.Select(childTaskId => CreateTaskLayoutInfos(tree, childTaskId))).ToArray(); node.LaneWidth = node.Children.Sum(i => i.LaneWidth); } } } return(node); }
private void OnCreateTaskCommand(CreateTaskCommand command) { var parent = Repository.States[command.Id]; var parentTaskId = 0u; if (parent is BehaviorTreeState) { var tree = (BehaviorTreeState)parent; if (tree.RootTaskId > 0) { parent.ApplyEvent(new TaskNotCreatedEvent(command.Id) { Reason = "Behavior tree already has root task" }); return; } } else if (parent is TaskState) { var task = (TaskState)parent; if (task.Desc is LeafTaskDescWrapper) { parent.ApplyEvent(new TaskNotCreatedEvent(command.Id) { Reason = "Leaf task cannot have child task" }); return; } else if (task.Desc is DecoratorTaskDescWrapper) { var desc = (DecoratorTaskDescWrapper)task.Desc; if (desc.ChildTaskId != 0) { parent.ApplyEvent(new TaskNotCreatedEvent(command.Id) { Reason = "Decorator task can only has one child task" }); return; } } parentTaskId = task.Desc.Id; } else { throw new NotSupportedException(command.Id); } { var tree = (BehaviorTreeState)Repository.States[BehaviorTreeState.GetId()]; TaskDescWrapper taskDescWrapper; if (typeof(ILeafTaskDesc).IsAssignableFrom(command.TaskType)) { taskDescWrapper = new LeafTaskDescWrapper(); } else if (typeof(IDecoratorTaskDesc).IsAssignableFrom(command.TaskType)) { taskDescWrapper = new DecoratorTaskDescWrapper(); } else if (typeof(ICompositeTaskDesc).IsAssignableFrom(command.TaskType)) { taskDescWrapper = new CompositeTaskDescWrapper(); } else { throw new NotSupportedException(command.TaskType.ToString()); } taskDescWrapper.Id = tree.NextTaskId; taskDescWrapper.CustomDesc = (ITaskDesc)Activator.CreateInstance(command.TaskType); var taskState = new TaskState(Domain, TaskState.GetId(tree.NextTaskId)); taskState.ParentTaskId = parentTaskId; taskState.Desc = taskDescWrapper; parent.ApplyEvent(new TaskCreatedEvent(command.Id) { NewTask = taskState }); } }