private void CreateOutputPorts()
        {
            output = node switch
            {
                CompositeNode _ => InstantiatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Multi,
                                                   typeof(bool)),
                DecoratorNode _ => InstantiatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Single,
                                                   typeof(bool)),
                _ => output
            };

            if (output == null)
            {
                return;
            }

            output.portName = "";
            outputContainer.Add(output);
        }
Esempio n. 2
0
        // sets this node and its children to the idle state
        void SetNodeTreeIdle(Node n)
        {
            var nodeName = n.ToString();

            // decorator node
            if (nodeName == "Inverter" || nodeName == "Repeater" || nodeName == "RepeatTillFail" || nodeName == "Limiter" || nodeName == "Succeeder")
            {
                DecoratorNode d = (DecoratorNode)n;
                SetNodeTreeIdle(d.ChildNode);
            }
            // composite node
            else if (nodeName == "Selector" || nodeName == "Sequence")
            {
                CompositeNode c = (CompositeNode)n;
                foreach (Node childNode in c.ChildNodeList)
                {
                    SetNodeTreeIdle(childNode);
                }
            }

            n.NodeState = ENodeStates.IDLE;
        }
Esempio n. 3
0
    private void BuildBehaviourTree()
    {
        var chaseAction              = new ActionNode(Chase);
        var canChaseDecorator        = new DecoratorNode(chaseAction, () => remainingTimeToChase > 0.0f);
        var approachAction           = new ActionNode(ApproachToTarget);
        var canApproachDecorator     = new DecoratorNode(approachAction, () => isTargetInDetectionArea);
        var selector1                = new SelectorNode(canApproachDecorator, canChaseDecorator);
        var fireAction               = new ActionNode(Fire);
        var canFireDecorator         = new DecoratorNode(fireAction, () => { return(gun.CanFire()); });
        var faceToTargetAction       = new ActionNode(FaceToTarget);
        var selector2                = new SelectorNode(canFireDecorator, faceToTargetAction);
        var canSeeTargetDecorator    = new DecoratorNode(selector2, CanSeeTarget);
        var selector3                = new SelectorNode(canSeeTargetDecorator, approachAction);
        var isTargetInRangeDecorator = new DecoratorNode(selector3, () => isTargetInRange);
        var selector4                = new SelectorNode(isTargetInRangeDecorator, selector1);
        var isTargetNullDecorator    = new DecoratorNode(selector4, () => { return(target != null); });
        var waitAction               = new ActionNode(Wait);
        var selector5                = new SelectorNode(isTargetNullDecorator, waitAction);
        var blownChecker             = new DecoratorNode(waitAction, () => { return(core.isBlown); });
        var selector6                = new SelectorNode(blownChecker, selector5);

        behaviourTree = new BehaviourTree(selector6);
    }
Esempio n. 4
0
    public INode CreateRandomSelectorTest()
    {
        NodeFactory      factory          = FactoryManager.Instance.GetFactory <NodeFactory>(FactoryType.Node);
        ConditionFactory conditionFactory = FactoryManager.Instance.GetFactory <ConditionFactory>(FactoryType.Condition);
        DecoratorFactory decoratorFactory = FactoryManager.Instance.GetFactory <DecoratorFactory>(FactoryType.Decorator);

        var rootNode = factory.Create <RootNode>(NodeType.Root);
        RandomSelectorNode randomSelectorNode = factory.Create <RandomSelectorNode>(NodeType.RandomSelector);
        DecoratorNode      decoratorNode      = factory.Create <DecoratorNode>(NodeType.Decorator);
        FalseDecorator     not = decoratorFactory.Create <FalseDecorator>(DecoratorType.False);

        decoratorNode.SetDecoratable(not);
        var actionNode1 = CreateSampleActionNode1();
        var actionNode2 = CreateSampleActionNode1();
        var actionNode3 = CreateSampleActionNode2();

        randomSelectorNode.AddNode(actionNode1);
        randomSelectorNode.AddNode(actionNode2);
        decoratorNode.AddNode(actionNode3);
        randomSelectorNode.AddNode(decoratorNode);
        rootNode.AddNode(randomSelectorNode);
        return(rootNode);
    }
Esempio n. 5
0
 void DrawDecorator(DecoratorNode decorator)
 {
     //if node is a decorator, draw child and widgets.
     if (decorator != null)
     {
         if (ReactTypeRegister.IsCoreDecorator(decorator.GetType()))
         {
             DrawCoreDecorator(decorator);
         }
         if (decorator.Child != null)
         {
             cursor.x += decorator.rect.width + SPACING.x;
             cursor.y -= decorator.rect.height + SPACING.x / 2;
             Draw(decorator.Child, decorator);
             // var left = decorator.rect.xMax;
             // var mid = decorator.rect.center.y;
             // var right = decorator.Child.rect.xMin;
             // ReactEditorUtility.DrawLine(new Vector2(left, mid), new Vector3(right, mid), Color.white);
             cursor.x -= decorator.rect.width + SPACING.x;
         }
         dropZones.Add(new DropZone(decorator, decorator.rect));
     }
 }
Esempio n. 6
0
 /// <summary>
 /// clone
 /// </summary>
 /// <returns></returns>
 public IBehaviourNode Clone()
 {
     var behaviourNode = new DecoratorNode();
     base.CopyToCompositeNode(behaviourNode);
     return behaviourNode;
 }
        private void InitializeTreeView()
        {
            StockNode treeNode1;

             foreach (string entry in this.theme.Keys)
             {
            if (entry.ToUpper().EndsWith("GRAPH"))
            {
               GraphNode treeNode = new GraphNode(entry, this.graphMenuStrip, Color.White, Color.LightGray, true, Color.LightGray, GraphChartMode.BarChart);
               if (entry.ToUpper().Contains("VOLUME"))
               {
                  treeNode.ImageKey = "VH";
                  treeNode.SelectedImageKey = "VH";
               }
               this.treeView1.Nodes.Add(treeNode);

               foreach (string line in this.theme[entry])
               {
                  try
                  {
                     string[] fields = line.Split('|');
                     switch (fields[0].ToUpper())
                     {
                        case "GRAPH":
                           string[] colorItem = fields[1].Split(':');
                           treeNode.GraphBackgroundColor = Color.FromArgb(int.Parse(colorItem[0]), int.Parse(colorItem[1]), int.Parse(colorItem[2]), int.Parse(colorItem[3]));
                           colorItem = fields[2].Split(':');
                           treeNode.GraphTextBackgroundColor = Color.FromArgb(int.Parse(colorItem[0]), int.Parse(colorItem[1]), int.Parse(colorItem[2]), int.Parse(colorItem[3]));
                           treeNode.GraphShowGrid = bool.Parse(fields[3]);
                           colorItem = fields[4].Split(':');
                           treeNode.GraphGridColor = Color.FromArgb(int.Parse(colorItem[0]), int.Parse(colorItem[1]), int.Parse(colorItem[2]), int.Parse(colorItem[3]));
                           treeNode.GraphMode = (GraphChartMode)Enum.Parse(typeof(GraphChartMode), fields[5]);
                           if (treeNode.Text.ToUpper() == "CLOSEGRAPH")
                           {
                              if (fields.Length >= 7)
                              {
                                 treeNode.SecondaryPen = GraphCurveType.PenFromString(fields[6]);
                              }
                              else
                              {
                                 treeNode.SecondaryPen = new Pen(Color.DarkGoldenrod, 1);
                              }
                           }
                           break;
                        case "DATA":
                           if (treeNode.Text.ToUpper() == "CLOSEGRAPH")
                           {
                              if (fields[1] == "CLOSE")
                              {
                                 treeNode1 = new CurveNode(fields[1], null, GraphCurveType.PenFromString(fields[2]), bool.Parse(fields[3]));
                                 treeNode.Nodes.Add(treeNode1);
                              }
                              else
                              {
                                 if (bool.Parse(fields[3])) // Normaly Other than close is not visible...
                                 {
                                    treeNode1 = new CurveNode(fields[1], null, GraphCurveType.PenFromString(fields[2]), bool.Parse(fields[3]));
                                    treeNode.Nodes.Add(treeNode1);
                                 }
                              }
                           }
                           else
                           {
                              if (fields[1] != "VOLUME" && bool.Parse(fields[3])) // Normaly Other than close is not visible...
                              {
                                 treeNode1 = new CurveNode(fields[1], null, GraphCurveType.PenFromString(fields[2]), bool.Parse(fields[3]));
                                 treeNode.Nodes.Add(treeNode1);
                              }
                           }
                           break;
                        case "INDICATOR":
                           {
                              IStockIndicator stockIndicator = (IStockIndicator)StockViewableItemsManager.GetViewableItem(line);
                              treeNode1 = new IndicatorNode(stockIndicator.Name, this.indicatorMenuStrip, stockIndicator);
                              for (int i = 0; i < stockIndicator.SeriesCount; i++)
                              {
                                 CurveNode curveNode = new CurveNode(stockIndicator.SerieNames[i], null, stockIndicator.SeriePens[i], true, stockIndicator.SerieVisibility[i]);
                                 treeNode1.Nodes.Add(curveNode);

                                 curveNode.ImageKey = treeNode1.ImageKey;
                                 curveNode.SelectedImageKey = treeNode1.SelectedImageKey;
                              }
                              treeNode.Nodes.Add(treeNode1);
                           }
                           break;
                        case "PAINTBAR":
                           {
                              IStockPaintBar stockPaintBar = (IStockPaintBar)StockViewableItemsManager.GetViewableItem(line);
                              treeNode1 = new PaintBarsNode(stockPaintBar.Name, this.indicatorMenuStrip, stockPaintBar);
                              for (int i = 0; i < stockPaintBar.SeriesCount; i++)
                              {
                                 CurveNode curveNode = new CurveNode(stockPaintBar.SerieNames[i], null, stockPaintBar.SeriePens[i], true, stockPaintBar.SerieVisibility[i]);
                                 treeNode1.Nodes.Add(curveNode);

                                 curveNode.ImageKey = treeNode1.ImageKey;
                                 curveNode.SelectedImageKey = treeNode1.SelectedImageKey;
                              }
                              treeNode.Nodes.Add(treeNode1);
                           }
                           break;
                        case "TRAILSTOP":
                           {
                              IStockTrailStop stockTrailStop = (IStockTrailStop)StockViewableItemsManager.GetViewableItem(line);
                              treeNode1 = new TrailStopsNode(stockTrailStop.Name, this.indicatorMenuStrip, stockTrailStop);
                              for (int i = 0; i < stockTrailStop.SeriesCount; i++)
                              {
                                 CurveNode curveNode = new CurveNode(stockTrailStop.SerieNames[i], null, stockTrailStop.SeriePens[i], false, true);
                                 treeNode1.Nodes.Add(curveNode);

                                 curveNode.ImageKey = treeNode1.ImageKey;
                                 curveNode.SelectedImageKey = treeNode1.SelectedImageKey;
                              }
                              treeNode.Nodes.Add(treeNode1);
                           }
                           break;
                        case "DECORATOR":
                           {
                              IStockDecorator stockDecorator = (IStockDecorator)StockViewableItemsManager.GetViewableItem(line);
                              treeNode1 = new DecoratorNode(stockDecorator.Name, this.indicatorMenuStrip, stockDecorator);
                              for (int i = 0; i < stockDecorator.SeriesCount; i++)
                              {
                                  treeNode1.Nodes.Add(new CurveNode(stockDecorator.SerieNames[i], null, stockDecorator.SeriePens[i], true, stockDecorator.SerieVisibility[i]));
                              }
                              for (int i = 0; i < stockDecorator.EventCount; i++)
                              {
                                  treeNode1.Nodes.Add(new EventNode(stockDecorator.EventNames[i], null, stockDecorator.EventPens[i], true, stockDecorator.EventVisibility[i]));
                              }
                              foreach (TreeNode childNode in treeNode.Nodes)
                              {
                                 if (childNode.Text == stockDecorator.DecoratedItem)
                                 {
                                    childNode.Nodes.Add(treeNode1);
                                    break;
                                 }
                              }
                           }
                           break;
                        case "TRAIL":
                           {
                              IStockTrail stockTrail = (IStockTrail)StockViewableItemsManager.GetViewableItem(line);
                              treeNode1 = new TrailNode(stockTrail.Name, this.indicatorMenuStrip, stockTrail);
                              for (int i = 0; i < stockTrail.SeriesCount; i++)
                              {
                                 treeNode1.Nodes.Add(new CurveNode(stockTrail.SerieNames[i], null, stockTrail.SeriePens[i], true, true));
                              }
                              foreach (TreeNode childNode in treeNode.Nodes)
                              {
                                 if (childNode.Text == stockTrail.TrailedItem)
                                 {
                                    childNode.Nodes.Add(treeNode1);
                                    break;
                                 }
                              }
                           }
                           break;
                        case "LINE":
                           treeNode.Nodes.Add(new LineNode("LINE_" + fields[1], this.indicatorMenuStrip, GraphCurveType.PenFromString(fields[2]), float.Parse(fields[1])));
                           break;
                        default:
                           continue;
                     }
                  }
                  catch (System.Exception e)
                  {
                     StockLog.Write(e);
                  }
               }
            }
             }
             foreach (TreeNode node in this.treeView1.Nodes)
             {
            node.Expand();
             }
             this.treeView1.SelectedNode = treeView1.Nodes[0];
        }
        void addDecoratorToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            AddDecoratorDlg addDlg;
             StockNode treeNode = (StockNode)this.treeView1.SelectedNode;
             switch (treeNode.Text)
             {
            case "CloseGraph":
               return;
            case "VolumeGraph":
               return;
            default:
               addDlg = new AddDecoratorDlg();
               break;
             }
             if (addDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
             {
            StockNode stockNode = (StockNode)this.treeView1.SelectedNode;
            if (stockNode.Type == NodeType.Decorator) return;

            IStockDecorator stockDecorator = StockDecoratorManager.CreateDecorator(addDlg.DecoratorName, stockNode.Name);
            if (stockDecorator == null)
            {
               return;
            }
            if (stockDecorator.DisplayTarget != IndicatorDisplayTarget.PriceIndicator)
            {
               // Only one decorator per graph (except data serie) (multiple ema, BB, ....)
               int index = 0;
               bool found = false;
               foreach (StockNode node in stockNode.Nodes)
               {
                  if (node.Type == NodeType.Decorator)
                  {
                     found = true;
                     break;
                  }
                  index++;

               }
               if (found)
               {
                  stockNode.Nodes.RemoveAt(index);
               }
            }
            StockNode decoratorNode = new DecoratorNode(stockDecorator.Name, this.indicatorMenuStrip, stockDecorator);
            stockNode.Nodes.Add(decoratorNode);
            int i = 0;
            foreach (string curveName in stockDecorator.SerieNames)
            {
               decoratorNode.Nodes.Add(new CurveNode(curveName, null, stockDecorator.SeriePens[i], true));
               i++;
            }
            i = 0;
            foreach (string eventName in stockDecorator.EventNames)
            {
               decoratorNode.Nodes.Add(new EventNode(eventName, null, stockDecorator.EventPens[i], true));
               i++;
            }
            this.treeView1.SelectedNode = decoratorNode;
            decoratorNode.Expand();
             }
        }
Esempio n. 9
0
        public ApproachMachine()
        {
            DataStorage[PlayerPosition] = new Point(10, 10);
            DataStorage[GoalPosition]   = new Point(0, 0);
            DataStorage[Switch]         = false;

            var switchOffState = new State();

            this[SwitchOff] = switchOffState;
            switchOffState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOff");
                if ((bool)machine.DataStorage[Switch])
                {
                    machine.NextStateName = SwitchOn;
                }
            };

            var switchOnState = new State();

            this[SwitchOn] = switchOnState;

            var behaviourMachine = new BehaviourMachine();

            behaviourMachine.DataStorage.ReferTo(DataStorage, PlayerPosition);
            behaviourMachine.DataStorage.ReferTo(DataStorage, GoalPosition);

            switchOnState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOn");
                behaviourMachine.Execute();
            };

            var moveOrTeleportSelector = new SelectorNode();

            behaviourMachine.RegisterRootNode(moveOrTeleportSelector);

            var moveDecorator = new DecoratorNode();

            moveOrTeleportSelector.ChildNodes.Add(moveDecorator);
            moveDecorator.ConditionCallback = (machine, node) =>
            {
                Debug.WriteLine($"move condition check");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                Debug.WriteLine($"P:{playerPosition} G:{goalPosition}");
                return(!playerPosition.Equals(goalPosition));
            };
            var moveAction = new ActionNode();

            moveDecorator.ChildNode   = moveAction;
            moveAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"Move");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                var diffX          = Math.Abs(playerPosition.X - goalPosition.X);
                var diffY          = Math.Abs(playerPosition.Y - goalPosition.Y);
                if (diffX >= diffY)
                {
                    playerPosition.X += playerPosition.X > goalPosition.X ? -1 : 1;
                }
                else
                {
                    playerPosition.Y += playerPosition.Y > goalPosition.Y ? -1 : 1;
                }
                machine.DataStorage[PlayerPosition] = playerPosition;
                return(true);
            };

            var teleportAction = new ActionNode();

            teleportAction.DataStorage[TeleportCounter] = 10;
            moveOrTeleportSelector.ChildNodes.Add(teleportAction);
            teleportAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"teleport");
                var teleportCounter = (int)node.DataStorage[TeleportCounter];
                teleportCounter--;
                node.DataStorage[TeleportCounter] = teleportCounter;
                Debug.WriteLine($"teleport counter: {teleportCounter}");
                if (teleportCounter > 0)
                {
                    return(false);
                }

                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                playerPosition.X = new Random().Next(-10, 10);
                playerPosition.Y = new Random().Next(-10, 10);
                machine.DataStorage[PlayerPosition] = playerPosition;

                node.DataStorage[TeleportCounter] = 10;
                Debug.WriteLine($"teleport to {playerPosition}");
                return(true);
            };
        }
Esempio n. 10
0
    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();
    }
Esempio n. 11
0
        // Use this for initialization
        private void Start()
        {
            var        waitPositonTime = 0f;
            GameObject attackPlayer    = null;
            var        isMoveTerget    = false;
            var        moveTerget      = Vector3.zero;
            GameObject itemObject      = null;
            var        coolTime        = 0f;

            // 行き先に向かって移動する
            this.UpdateAsObservable()
            .Where(_ => isMoveTerget)
            .Select(_ =>
            {
                var path     = new NavMeshPath();
                isMoveTerget = NavMesh.CalculatePath(transform.position, moveTerget, NavMesh.AllAreas, path);
                return(path);
            })
            .Where(x => x.corners.Length >= 2)
            .Do(_ => waitPositonTime = 0f)     // 行き先を見つけた
            .Select(x => (x.corners[1] - x.corners[0]).normalized)
            .Select(x => AI_Extension.CalcDoc(x))
            .Subscribe(moveDirectionSubject);

            // 止まっている時間のカウント
            this.UpdateAsObservable()
            .Where(_ => isMoveTerget == false)
            .Subscribe(_ => { waitPositonTime += Time.deltaTime; });

            // 止まっている時間が一定数立ってしまったらとりあえずターゲットに向かって歩く
            this.ObserveEveryValueChanged(_ => waitPositonTime)
            .Where(_ => isMoveTerget == false)
            .Where(x => x > 1f)
            .Where(_ => (Vector3.Distance(moveTerget, transform.position) > StopDistance * (1f - LevelMaxGettingUpToTimeRate)))      // 近くにすでにいるなら動かない
            .Select(_ => (moveTerget - transform.position).normalized)
            .Select(x => AI_Extension.CalcDoc(x))
            .Subscribe(moveDirectionSubject);

            // 行きたい位置についたら移動処理を停止させる
            this.UpdateAsObservable()
            .Where(_ => isMoveTerget)
            .Select(_ => Mathf.Abs(Vector3.Distance(moveTerget, transform.position)))
            .Where(x => x < StopDistance * (1f - LevelMaxGettingUpToTimeRate))
            .Subscribe(_ => isMoveTerget = false);

            // 敵の近くによったら攻撃する
            this.UpdateAsObservable()
            .Where(_ => attackPlayer != null)
            .Where(_ => (Vector3.Distance(attackPlayer.transform.position, this.transform.position) <= AttackDistance))
            .Subscribe(_ =>
            {
                onAttackButtonSubject.OnNext(true);
                onAttackButtonSubject.OnNext(false);
            });

            // アイテム生成通知
            StageSpawner.Instance.OnSpowenItemAsObservable()
            .Where(x => Vector3.Distance(x.transform.position, this.transform.position) < GetItemDistance)     // 自分の近くに生成された
            .Subscribe(x =>
            {
                // アイテムが存在していることを入れる
                itemObject = x;
                // 交戦中のプレイヤーを消しておく(取りに行くため)
                attackPlayer = null;
            });

            // アイテム存在チェック
            var checkNearItemState =
                new ActionNode("CheckItem", _ =>
            {
                if (itemObject != null)
                {
                    return(NodeStatusEnum.Success);
                }
                return(NodeStatusEnum.Failure);
            });

            // アイテムに近づくAI
            var goItemObject = new DecoratorNode("GoItemCheck",
                                                 new ActionNode("GoItem", _ =>
            {
                // 取れた取れてないにかかわらず終了
                if (itemObject == null)
                {
                    isMoveTerget = false;
                    return(NodeStatusEnum.Success);
                }
                // ターゲットを設定
                moveTerget   = itemObject.transform.position;
                moveTerget.y = transform.position.y;
                isMoveTerget = true;
                return(NodeStatusEnum.Running);
            })
                                                 , () => (itemObject != null));

            // 近くにアイテムがスポーンしたなら優先的に取り行くAI
            var checkItem = new SequenceNode("SearchItem",
                                             checkNearItemState // 生成してる
                                             , goItemObject     // 取りに行く
                                             );

            // 近くのプレイヤーを選択するAI
            var nearPlayer = new ActionNode("SearchPlayer",
                                            _ =>
            {
                // 生きているプレイヤー取得
                var players = PlayerManager.Instance.GetAlivePlayers();
                if (players.Count <= 1)
                {
                    isMoveTerget = false;
                    return(NodeStatusEnum.Failure);
                }

                // ソート
                players.Sort((x, y) =>
                {
                    var xDist = Vector3.Distance(x.transform.position, this.transform.position);
                    var yDist = Vector3.Distance(y.transform.position, this.transform.position);
                    if (xDist == yDist)
                    {
                        return(0);
                    }
                    if (xDist > yDist)
                    {
                        return(1);
                    }
                    else
                    {
                        return(-1);
                    }
                });
                // 一番近いプレイヤーを選択
                attackPlayer = players[1].gameObject;
                moveTerget   = AI_Extension.RandomPosition(attackPlayer.transform.position,
                                                           (1f - LevelMaxGettingUpToTimeRate)); // 時間経過で性格射撃になる
                moveTerget.y = transform.position.y;
                isMoveTerget = true;
                // 思考を停止するクールタイム
                coolTime  = Random.Range(0.5f, 2f);
                coolTime *= (1f - LevelMaxGettingUpToTimeRate);    // 時間経過で思考停止クールタイムがなくなる
                return(NodeStatusEnum.Success);
            }
                                            );

            var aiCoolTime = new ActionNode("CoolTime", _ =>
            {
                coolTime -= Time.deltaTime;
                if (coolTime < 0f)
                {
                    return(NodeStatusEnum.Failure);
                }
                return(NodeStatusEnum.Running);
            });

            // AI初期化
            BehaviorTreeComponent.RegsterComponent(this.gameObject, new SelectorNode("name",
                                                                                     checkItem,
                                                                                     aiCoolTime,
                                                                                     nearPlayer));
        }
Esempio n. 12
0
        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();
            }
        }