public override bool Build() { /* Creating new node with state data. * This node will set the destination which attached NPC will move to. * The pointer will exit this node when the NPC will be in the destination. */ //Preparing data Node start = NodeBuilder.Start(this); AddNode(start, null, "Start"); //Defining action which will be invoked when the pointer will enter our node Action onEnter = delegate { npcOwner.Agent.SetDestination(GameObject.Find("Waypoint").transform.position); }; //Defining condition which will move pointer to the next node Func <bool> condition = delegate { return(npcOwner.Agent.InDestination()); }; //Creating data object StateData data = new StateData(onEnter, null, null, (condition, 0)); //Creating node Node movingNode = new Node(data); //Adding node and connect to the start node AddNode(movingNode, null, "Moving node"); /* Let's create other node, which will print the message "Test debug" when the pointer reaches this node. * Pointer will exit this node automatically. */ //Debug log node data StateData debugLogData = new StateData(delegate { Debug.Log("Test debug"); }, null, null); //Debug log node itself Node debugLogNode = new Node(debugLogData); //Adding node and connect to the (earlier created) moving node AddNode(debugLogNode, movingNode, "Debug node"); //Let's create a node which will set the destination as second waypoint //Create node object (similar to movingNode) Node moveBackNode = new Node( new StateData( delegate { npcOwner.Agent.SetDestination(GameObject.Find("Waypoint2").transform.position); }, null, null, (delegate { return(npcOwner.Agent.InDestination()); }, 0) ) ); //Add new node to the tree AddNode(moveBackNode, debugLogNode, "Move back node"); //Connect new node to the start node, whereby our tree becomes endless. ConnectNodes("Move back node", "Moving node"); return(true); }
public override bool Build() { InterruptCondition = delegate { return(npcOwner.IsDead); }; #region Start Group Node start = NodeBuilder.Start(this); AddNode(start, null, "Start"); #endregion #region Nodes Initialize Node shoot = null; Node idle = null; Node searchForActor = null; //TODO: Rewrite nodes code using NodeContainers (in order to get rid of strings) NodeContainer shootContainer = new NodeContainer(shoot); NodeContainer idleContainer = new NodeContainer(idle); NodeContainer searchForActorContainer = new NodeContainer(searchForActor); #endregion #region Idle state //TODO: Remove this unneccesary condition Func <bool> seesActorCondition = delegate { return(npcOwner.focusedTarget != null && npcOwner.CanSeeActor(npcOwner.focusedTarget)); }; Func <bool> seesEnemyCondition = delegate { return(npcOwner.focusedTarget != null && npcOwner.focusedTarget.ActorFraction != npcOwner.ActorFraction && !npcOwner.focusedTarget.IsDead); }; StateData idleStateData = new StateData ( null, null, delegate { npcOwner.Animator.SetTrigger("Idle" + npcOwner.EquipedWeapon.Settings.HoldingType.ToString()); }, (seesActorCondition, 0) ); idle = new Node(idleStateData); idleContainer.AttachedNode = idle; Node idleSeesActorSwitch = NodeBuilder.Switch("Idle State", ("Shoot State", seesEnemyCondition)); AddNode(idle, start, "Idle State"); AddNode(idleSeesActorSwitch, idle, "Idle State: Sees actor switch"); #endregion #region Shoot State Func <bool> enemyIsDead = delegate { return(npcOwner.focusedTarget != null && npcOwner.focusedTarget.IsDead); }; Action shootingAction = delegate { npcOwner.ShootInActor(npcOwner.focusedTarget); }; StateData shootStateData = new StateData ( null, null, delegate { Debug.Log("Shoot on sate"); shootingAction.Invoke(); }, //On update (enemyIsDead, 0), (() => { return(true); }, 1) ); shoot = new Node(shootStateData); shootContainer.AttachedNode = shoot; AddNode(shoot, idleSeesActorSwitch, "Shoot State"); // Idle is now child of shooting state with localId = 0 ConnectNodes("Shoot State", "Idle State"); Action searchForActorContext = delegate { // Interruption if (seesActorCondition() && seesEnemyCondition()) { searchForActor.Exit(); } }; Func <bool> noSearchResultCondition = delegate { return(npcOwner.Agent.InDestination()); }; StateData searchForActorData = new StateData ( () => { npcOwner.Agent.SetDestination(npcOwner.TargetLastSeenPosition); }, null, searchForActorContext, (noSearchResultCondition, 1) ); searchForActor = new Node(searchForActorData); searchForActorContainer.AttachedNode = searchForActor; // Shooting choice-node with localId = 1 Node shootingChoiceNode = NodeBuilder.Choice ( "Shoot State", "Shoot State: Search State", () => { return(npcOwner.focusedTarget != null && !npcOwner.focusedTarget.IsDead && npcOwner.CanSeeActor(npcOwner.focusedTarget)); } ); AddNode(shootingChoiceNode, shoot, "Shoot State: Choice"); AddNode(searchForActor, shoot, "Shoot State: Search State"); // shoot is now child of searchForActor with localId = 0 ConnectNodes("Shoot State: Search State", "Shoot State"); // idle is now child of searchForActor with localId = 1 ConnectNodes("Shoot State: Search State", "Idle State"); #endregion return(true); }