public Node Create(NodeType type) { Node node = null; switch (type) { case NodeType.Root: node = new RootNode(); break; case NodeType.Action: node = new ActionNode(); break; case NodeType.Sequencer: node = new SequencerNode(); break; case NodeType.Selector: node = new SelectorNode(); break; case NodeType.Random: node = new RandomNode(); break; case NodeType.RandomSelector: node = new RandomSelectorNode(); break; case NodeType.RandomSequencer: node = new RandomSequencerNode(); break; case NodeType.Decorator: node = new DecoratorNode(); break; case NodeType.Condition: node = new ConditionNode(); break; case NodeType.ConditionWhile: node = new ConditionWhileNode(); break; default: Debug.Assert(false, "未定義のノードタイプ"); break; } if (node != null) { node.Init(idSeed); Register(idSeed, node); idSeed += 1; } return(node); }
private void NodeActive_CheckChanged(object sender, EventArgs e) { CheckBox o = (CheckBox)sender; SequencerNode node = pEngine.GetNodeInSequencer(FormNameFormating.GetPanelIndex(o), FormNameFormating.GetNodeIndex(o)); node.Active = o.Checked; }
private void NodeGate_ValueChanged(object sender, EventArgs e) { NumericUpDown o = (NumericUpDown)sender; SequencerNode node = pEngine.GetNodeInSequencer(FormNameFormating.GetPanelIndex(o), FormNameFormating.GetNodeIndex(o)); node.GateTime = (int)o.Value; }
// Use this for initialization void Start() { //nodes rootNode = new SelectorNode(); //sequensers sequencer1 = new SequencerNode(); sequencer2 = new SequencerNode(); //selectors selector1 = new SelectorNode(); selector2 = new SelectorNode(); //repeaters repeatUntilFail1 = new RepeatUntilFailNode(); //behaviours leaf leafNodeIdle = new LeafNodeIdle(); leafNodeMove = new LeafNodeMove(); leafNodeMoveAway = new leafNodeMoveAway(); //behaviours nodes nodeChooseAttack = new NodeChooseAttack(); //repeater nodes repeatSetTimes1 = new RepeatSetTimesNode(); //check distance decorator checkdst = new DecoratorNodeCheckDist(); bb = new Blackboard(); bb.Boss = GameObject.FindGameObjectWithTag("Boss"); bb.agent = bb.Boss.GetComponent <NavMeshAgent>(); bb.closestEnemyCursor = GameObject.FindGameObjectWithTag("Player"); bb.movespeed = bossMoveSpeed; bb.aggroRange = bossAggroRange; bb.rotationSpeed = bossRotationSpeed; bb.maxValHealth = 100f; bb.maxValTwoHealth = 100f; bb.currentValHealth = 100f; bb.currentValTwoHealth = 100f; bb.fillAmountHealth = 1f; bb.fillAmountTwoHealth = 1f; //node inits rootNode.InitSelector(bb, "Root"); nodeChooseAttack.InitAttack(bb, "Attack"); leafNodeIdle.InitIdle(bb, "Idle"); leafNodeMove.InitMove(bb, "Move"); leafNodeMoveAway.Init(bossMoveSpeed, bossRotationSpeed); selector1.InitSelector(bb, "Selector"); sequencer1.InitSequenser(bb, "Sequence"); checkdst.initDistCheck(bb, "distanceCheck"); //sequence one children rootNode.GetController().AddChild(selector1); selector1.GetController().AddChild(leafNodeIdle); selector1.GetController().AddChild(sequencer1); sequencer1.GetController().AddChild(leafNodeMove); sequencer1.GetController().AddChild(checkdst); sequencer1.GetController().AddChild(nodeChooseAttack); //test for debug rootNode.SetCurrentTask(rootNode.GetController().GetChildList().First()); selector1.SetCurrentTask(selector1.GetController().GetChildList().First()); sequencer1.SetCurrentTask(sequencer1.GetController().GetChildList().First()); }
void Start() { _behaviorTreeController = new BehaviorTreeController(); // rootとなるSequencer SequencerNode rootNode = new SequencerNode(); rootNode.name = "rootノード"; // 出発 ActionNode departure = new ActionNode(); departure.name = "出発する"; departure.SetRunningFunc(() => { Debug.LogError("出発"); return(NodeStatus.SUCCESS); }); // HP確認のDecorator DecoratorNode confirmationHp = new DecoratorNode(); confirmationHp.name = "HP確認するのDecorator"; confirmationHp.SetConditionFunc(() => { return(_myHp >= 100 ? NodeStatus.SUCCESS : NodeStatus.FAILURE); }); // 敵に寄る ActionNode enemyApproach = new ActionNode(); enemyApproach.name = "敵に寄るアクションノード"; enemyApproach.SetRunningFunc(() => { Debug.LogError("敵に寄る"); return(NodeStatus.SUCCESS); }); // HP確認のDecoratorの子供登録 confirmationHp.AddChild(enemyApproach); // 友達2人を呼ぶParallelNode ParallelNode callFriendAB = new ParallelNode(); callFriendAB.name = "友達2人を呼ぶParallelNode"; // 友達A ActionNode friendA = new ActionNode(); friendA.name = "友達Aを呼ぶ"; friendA.SetRunningFunc(() => { Debug.LogError("友達A"); return(NodeStatus.SUCCESS); }); // 友達B ActionNode friendB = new ActionNode(); friendB.name = "友達Bを呼ぶ"; friendB.SetRunningFunc(() => { Debug.LogError("友達B"); return(NodeStatus.SUCCESS); }); // 友達2人を呼ぶParallelNodeの子供登録 callFriendAB.AddChild(friendA); callFriendAB.AddChild(friendB); // スキルを繰り返し行うRepeaterNode RepeaterNode skillRepeater = new RepeaterNode(); skillRepeater.name = "スキルを繰り返し行うRepeaterNode"; // スキルを選択するSelector SelectorNode selectSkill = new SelectorNode(); selectSkill.name = "スキルを選択するSelector"; // スキルAの発動を確認するDecorator DecoratorNode triggerSkillA = new DecoratorNode(); triggerSkillA.name = "スキルAの発動を確認するDecorator"; triggerSkillA.SetConditionFunc(() => { int probability = Mathf.Clamp(probabilitySkillA, 0, 100); int random = Random.Range(0, 100); return(probability > random ? NodeStatus.SUCCESS : NodeStatus.FAILURE); }); // スキルA ActionNode skillA = new ActionNode(); skillA.name = "skillA"; skillA.SetRunningFunc(() => { Debug.LogError("skillA"); _enemyHp -= 50; return(NodeStatus.SUCCESS); }); // スキルAの発動を確認するDecoratorの子供登録 triggerSkillA.AddChild(skillA); // スキルB ActionNode skillB = new ActionNode(); skillB.name = "skillB"; skillB.SetRunningFunc(() => { Debug.LogError("skillB"); _enemyHp -= 60; return(NodeStatus.SUCCESS); }); // スキルを選択するSelectorの子供登録 selectSkill.AddChild(triggerSkillA); selectSkill.AddChild(skillB); // スキルを繰り返し行うRepeaterNodeの子供登録 skillRepeater._repeatNum = 2; skillRepeater.AddChild(selectSkill); // 敵の生存を確認するSelector SelectorNode enemySurvial = new SelectorNode(); enemySurvial.name = "敵の生存を確認するSelector"; // 敵が死んでいるか確認するDecorator DecoratorNode enemyDied = new DecoratorNode(); enemyDied.name = "敵が死んでいるか確認するDecorator"; enemyDied.SetConditionFunc(() => { return(_enemyHp <= 0 ? NodeStatus.SUCCESS : NodeStatus.FAILURE); }); // 敵が死んでいる ActionNode died = new ActionNode(); died.name = "敵が死んでいる"; died.SetRunningFunc(() => { Debug.LogError("End1"); Debug.LogError("EnemyHp : " + _enemyHp); return(NodeStatus.SUCCESS); }); // 敵が死んでいるか確認するDecoratorの子供登録 enemyDied.AddChild(died); // 敵が生きているか確認するDecorator DecoratorNode enemyAlive = new DecoratorNode(); enemyAlive.name = "敵が生きているか確認するDecorator"; enemyAlive.SetConditionFunc(() => { return(_enemyHp > 0 ? NodeStatus.SUCCESS : NodeStatus.FAILURE); }); // 敵が生きている ActionNode alive = new ActionNode(); alive.name = "敵が生きている"; alive.SetRunningFunc(() => { Debug.LogError("End2"); Debug.LogError("EnemyHp : " + _enemyHp); return(NodeStatus.SUCCESS); }); // 敵が生きているか確認するDecoratorの子供登録 enemyAlive.AddChild(alive); // 敵の生存を確認するSelectorの子供登録 enemySurvial.AddChild(enemyDied); enemySurvial.AddChild(enemyAlive); // rootノードの子供登録 rootNode.AddChild(departure); rootNode.AddChild(confirmationHp); rootNode.AddChild(callFriendAB); rootNode.AddChild(skillRepeater); rootNode.AddChild(enemySurvial); // ツリー実行 _behaviorTreeController.Initialize(rootNode); _behaviorTreeController.OnStart(); }
public void SimpleSearcherTest() { const string hitpoint = "hp"; const string distanceToTower = "distance"; var machine = new BehaviourMachine(); machine.DataStorage[hitpoint] = 100; machine.DataStorage[distanceToTower] = 10; machine.OnExecuteEvent += (m) => { var hp = (int)m.DataStorage[hitpoint]; var distance = (int)m.DataStorage[distanceToTower]; Debug.WriteLine($"HP: {hp}"); Debug.WriteLine($"Distance: {distance}"); }; var selector = new SelectorNode(); machine.RegisterRootNode(selector); var decoratorHp = new DecoratorNode(); selector.ChildNodes.Add(decoratorHp); decoratorHp.ConditionCallback = (m, n) => m.DataStorage.GetValue <int>(hitpoint) > 5; var attackNearEnemy = new ActionNode(); attackNearEnemy.ActionCallback = (m, n) => { Debug.WriteLine("近くの敵を攻撃"); var distance = (int)m.DataStorage[distanceToTower]; distance += 1; m.DataStorage[distanceToTower] = distance; var hp = (int)m.DataStorage[hitpoint]; hp -= 5; m.DataStorage[hitpoint] = hp; return(true); }; decoratorHp.ChildNode = attackNearEnemy; var sequencer = new SequencerNode(); selector.ChildNodes.Add(sequencer); var moveToNearTower = new ActionNode(); sequencer.ChildNodes.Add(moveToNearTower); moveToNearTower.ActionCallback = (m, n) => { var distance = (int)m.DataStorage[distanceToTower]; if (distance <= 0) { return(true); } Debug.WriteLine("近くのタワーに移動"); distance--; m.DataStorage[distanceToTower] = distance; return(true); }; var wait = new ActionNode(); sequencer.ChildNodes.Add(wait); wait.ActionCallback = (m, n) => { Debug.WriteLine("待機"); var distance = (int)m.DataStorage[distanceToTower]; if (distance < 5) { var hp = (int)m.DataStorage[hitpoint]; hp += 20; m.DataStorage[hitpoint] = hp; } return(true); }; for (var i = 0; i < 100; i++) { machine.Execute(); } }