// Setup references and default values void Start() { // Get ref to the parent team objects to fill out team lists Transform RedTeamT = GameObject.Find("RedTeam").GetComponent <Transform>(); Transform BlueTeamT = GameObject.Find("BlueTeam").GetComponent <Transform>(); // Add all units to each team foreach (Transform child in RedTeamT) { RedTeam.Add(child.gameObject.GetComponent <Unit>()); } foreach (Transform child in BlueTeamT) { BlueTeam.Add(child.gameObject.GetComponent <Unit>()); } // Setting references layerMask = LayerMask.GetMask("Units"); tilemap = GameObject.Find("GridTileMap").GetComponent <Tilemap>(); tilemapFloor = GameObject.Find("BackroundTileMap").GetComponent <Tilemap>(); //tile floor astar = new Astar(); // access to astar methods ActiveUnitText = GameObject.Find("ActiveUnitText").GetComponent <Text>(); ActiveTeamText = GameObject.Find("ActiveTeamText").GetComponent <Text>(); UnitStateText = GameObject.Find("UnitStateText").GetComponent <Text>(); EnergyText = GameObject.Find("EnergyText").GetComponent <Text>(); HPText = GameObject.Find("HPText").GetComponent <Text>(); // Set red as first turn RedTeamTurn = true; approachSequence = new BTSequence(new List <BTNode> { new MoveToEnemyTask(this), }); attackSequence = new BTSequence(new List <BTNode> { new CheckForEnemyTask(this), new CheckEnemyHPTask(this), new AttackTask(this), }); attackSafeSequence = new BTSequence(new List <BTNode> { new CheckForEnemyTask(this), new AttackSafeTask(this), }); coverSequence = new BTSequence(new List <BTNode> { new MoveToCoverTask(this), }); rootAI = new BTSelector(new List <BTNode> { approachSequence, attackSequence, attackSafeSequence, coverSequence, }); }
public virtual void CreateBehaviourTree() { IsCoveredAvalibleBTNode isCoveredAvalibleBTNode = new IsCoveredAvalibleBTNode(avaliableCover, player, this); GoToCoverBTNode goToCoverBTNode = new GoToCoverBTNode(agent, this, controller); HealthBTNode healthBTNode = new HealthBTNode(controller); IsCoveredBTNode isCoveredBTNode = new IsCoveredBTNode(transform, player); ChaseBTNode chaseBTNode = new ChaseBTNode(player, agent, this); RangeBTNode chaseRange = new RangeBTNode(controller.ChaseRange, transform, player); ShootBTNode shootBTNode = new ShootBTNode(this, agent); RangeBTNode shootRangeBTNode = new RangeBTNode(controller.ShootRange, transform, player); ObstacleCheck obstacleCheck = new ObstacleCheck(transform, player); //IsShootAvailable isShootAvailable = new IsShootAvailable(transform, player); RangeBTNode meleeRange = new RangeBTNode(controller.MeleeRange, transform, player); MeleeBTNode meleeBTNode = new MeleeBTNode(this, agent); BTSequence chaseSequence = new BTSequence(new List<BTNode> { chaseRange, chaseBTNode }); BTSequence shootSequence = new BTSequence(new List<BTNode> { shootRangeBTNode, obstacleCheck, shootBTNode }); BTSequence meleeSequence = new BTSequence(new List<BTNode> { meleeRange, obstacleCheck, meleeBTNode }); BTSequence goToCoverSequence = new BTSequence(new List<BTNode> { isCoveredAvalibleBTNode, goToCoverBTNode }); BTSelector findCoverSelector = new BTSelector(new List<BTNode> { goToCoverSequence, chaseSequence }); BTSelector tryToFindSelctor = new BTSelector(new List<BTNode> { isCoveredBTNode, findCoverSelector }); BTSequence coverSequence = new BTSequence(new List<BTNode> { healthBTNode, tryToFindSelctor}); rootNode = new BTSelector(new List<BTNode> { coverSequence, meleeSequence, shootSequence, chaseSequence }); }
void Start() { //INIT playerCtrl = player.gameObject.GetComponent <CharacterController>(); //ACTIONS BTAction block = new BTAction(Block); BTAction meleeAttack = new BTAction(MeleeAttack); BTAction rangedAttack = new BTAction(RangedAttack); BTAction getCloser = new BTAction(GetCloser); //CONDITIONS BTCondition playerAttacking = new BTCondition(PlayerAttacking); BTCondition playerMelee = new BTCondition(PlayerMelee); BTCondition playerFar = new BTCondition(PlayerFar); //TREE BTSequence seqBlock = new BTSequence(new IBTTask[] { playerAttacking, block }); BTSequence seqMelee = new BTSequence(new IBTTask[] { playerMelee, meleeAttack }); BTSequence seqGetCloser = new BTSequence(new IBTTask[] { playerFar, getCloser }); BTDecorator untilFailGetCloser = new BTDecoratorUntilFail(seqGetCloser); BTRandomSelector rselRanged = new BTRandomSelector(new IBTTask[] { untilFailGetCloser, rangedAttack }); BTSelector selAttack = new BTSelector(new IBTTask[] { seqMelee, rselRanged }); root = new BTSelector(new IBTTask[] { seqBlock, selAttack }); }
/* --------------------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------------------*/ /* ------------------------------------- COMPOSITE NODES --------------------------------------*/ /* --------------------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------------------------*/ public BTSequence Sequence(params BTNode[] cs) { BTSequence node = new BTSequence(cs); node.bt = this; return(node); }
public override BTNode Init() { base.Init(); animator = GetComponent<Animator>(); BTSelector root = new BTSelector(); BTActionDeath death = new BTActionDeath(gameObject); root.AddChild(death); //领地限制的分支,只能在该范围活动 BTConditionEvaluator evaluatorTerritory = new BTConditionEvaluator(BTLogic.And, false, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); evaluatorTerritory.AddConditional(new BTCheckWithinDistance(_database.transform, territoryDis, null, BTCheckWithinDistance.DataOpt.FixedPosition), true); BTSimpleParallel goHome = new BTSimpleParallel(); { goHome.SetPrimaryChild(new BTActionCharacterMove(_database.transform, speed, 0.1f, null,BTActionMove.DataOpt.FixedPosition,BTActionMove.UsageOpt.Position, BTDataReadOpt.ReadEveryTick)); goHome.AddChild(new BTActionPlayAnimation(animator, "Walk")); } evaluatorTerritory.child = goHome; root.AddChild(evaluatorTerritory); BTConditionEvaluator evaluatorTarget = new BTConditionEvaluator(BTLogic.And, true, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); evaluatorTarget.AddConditional(new BTCheckExistence(_database.transform, defendDis, "Player", BTCheckExistence.CheckOpt.CheckSphere)); //加一层组合,来判断进行哪个动作 BTSelector actionSelector = new BTSelector(); evaluatorTarget.child = actionSelector; //评估是否有碰撞 BTConditionEvaluator evaluatorCollision = new BTConditionEvaluator(BTLogic.And, true, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); BTCheckCollision collision = new BTCheckCollision("Player", tolerance, BTCheckCollision.CheckOpt.RayCast); evaluatorCollision.AddConditional(collision); BTSequence attackSubtre = new BTSequence(); { attackSubtre.AddChild(new BTActionPlayAnimation(animator, "Attack")); } evaluatorCollision.child = attackSubtre; actionSelector.AddChild(evaluatorCollision); //没有碰撞则移动 BTSimpleParallel moveTo = new BTSimpleParallel(); { moveTo.SetPrimaryChild(new BTActionCharacterMove(_database.transform, speed, tolerance, target, BTDataReadOpt.ReadEveryTick)); moveTo.AddChild(new BTActionPlayAnimation(animator, "Walk")); } actionSelector.AddChild(moveTo); root.AddChild(evaluatorTarget); //Idle分支 BTActionPlayAnimation palyIdle = new BTActionPlayAnimation(animator, "Idle"); root.AddChild(palyIdle); return root; }
protected virtual BTSequence MoveSequence() { BTSequence sequence = new BTSequence(new List <BTNode>() { //new CanMoveCondition(this), //new FaceMoveDirectionTask(this), new MoveToTask(this) }); return(sequence); }
protected virtual BTSequence WanderSequence() { BTSequence sequence = new BTSequence(new List <BTNode>() { HasWaypointSelector(), new ReachedDestinationCondition(this), new SelectRandomWanderPoint(this), MoveSequence() }); return(sequence); }
protected virtual BTSequence CombatSequence() { BTSequence sequence = new BTSequence(new List <BTNode>() { new EnemySpottedCondition(this), InAttackRangeSelector(), new FaceMoveDirectionTask(this), new AttackTask(this) }); return(sequence); }
private void InitializePlayerPhaseBehaviourTree() { BTAction BTAct_CheckEndTurn = new BTAction( () => { if (mPlayerToEndPhase) { SwitchPhase(GamePhase.EnemyPhase); return(BTStatus.Running); } return(BTStatus.Success); } ); BTAction BTAct_MoveCard = new BTAction( () => { if (ControlAreaManager.CardIsBeingDragged) { return(BTStatus.Running); } return(BTStatus.Success); } ); BTAction BTAct_ExecuteCard = new BTAction( () => { if (ControlAreaManager.IsPanelOpen) { ControlAreaManager.Instance.SetControlBlockerEnabled(true); return(BTStatus.Running); } // Check player turn status. if (Player.TurnStatus == PlayerTurnStatus.Running) { ControlAreaManager.Instance.SetControlBlockerEnabled(true); return(BTStatus.Running); } if (EventAnimationController.Instance.IsAnimating == false) { ControlAreaManager.Instance.SetControlBlockerEnabled(false); } return(BTStatus.Success); } ); BTSequence BT_Root = new BTSequence(BTAct_CheckEndTurn, BTAct_MoveCard, BTAct_ExecuteCard); mPlayerPhaseBehaviourTree = new BehaviourTree(BT_Root); }
private void BuildBehaviourTree() { BTActionNode checkAIUnitsCountCriticalNode = new BTActionNode(CheckAIUnitsCountCritical); BTActionNode findWeakestPlayerUnitNode = new BTActionNode(FindWeakestPlayerUnit); BTActionNode findClosetPlayerUnitNode = new BTActionNode(FindClosestPlayerUnit); BTActionNode moveTowardsThePlayerUnitNode = new BTActionNode(MoveTowardsThePlayerUnit); BTActionNode attackPlayerUnitNode = new BTActionNode(AttackPlayerUnit); BTSequence MoveTowardsAndAttackSequence = new BTSequence(new List <BTNode>() { moveTowardsThePlayerUnitNode, attackPlayerUnitNode }); BTSequence WeakestPlayerAttackSequence = new BTSequence(new List <BTNode>() { findWeakestPlayerUnitNode, MoveTowardsAndAttackSequence }); BTSequence aiWeakSequence = new BTSequence(new List <BTNode>() // check if the AI count is less than or eaqual to player count, al { checkAIUnitsCountCriticalNode, WeakestPlayerAttackSequence, }); BTSequence aiStrongSequence = new BTSequence(new List <BTNode>() //moment I am checking againt unit, also can have centralized AI score, => health of all unts + unt count { findClosetPlayerUnitNode, MoveTowardsAndAttackSequence, }); BTSelector selectorRoot = new BTSelector(new List <BTNode>() { aiWeakSequence, aiStrongSequence }); _behvourTree = new BehaviourTree(selectorRoot); }
private BTNode LoadBTNode(XmlNode currentNode, AI owner, MacroAIParty party) { XmlNodeList nodeContent = currentNode.ChildNodes; XmlAttributeCollection nodeAttributes = currentNode.Attributes; BTNode node = null; if (currentNode.Name == "behavior") { node = LoadBTNode(nodeContent[0], owner, party); } else if (currentNode.Name == "composite") { BTComposite compNode = null; if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Sequence") { BTSequence seqNode = new BTSequence(); seqNode.CompNodeType = BTCompType.Sequence; compNode = seqNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Selector") { BTSelector selNode = new BTSelector(); selNode.CompNodeType = BTCompType.Selector; compNode = selNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "ParallelAnd") { BTParallelAnd parNode = new BTParallelAnd(); parNode.CompNodeType = BTCompType.ParallelAnd; compNode = parNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "ParallelMain") { BTParallelMain parNode = new BTParallelMain(); parNode.CompNodeType = BTCompType.ParallelMain; compNode = parNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Random") { BTRandom randNode = new BTRandom(); randNode.CompNodeType = BTCompType.Random; compNode = randNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Switch") { BTSwitch swNode = new BTSwitch(); swNode.CompNodeType = BTCompType.Switch; compNode = swNode; } compNode.Children = new List <BTNode>(); foreach (XmlNode nodeItem in nodeContent) { compNode.Children.Add(LoadBTNode(nodeItem, owner, party)); } node = compNode; } else if (currentNode.Name == "decorator") { BTDecorator decNode = null; if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Repeat") { BTRepeat repNode = new BTRepeat(); decNode = repNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Invert") { BTInvert invNode = new BTInvert(); decNode = invNode; } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "UntilFail") { BTUntilFail repNode = new BTUntilFail(); decNode = repNode; } foreach (XmlNode nodeItem in nodeContent) { decNode.Child = LoadBTNode(nodeItem, owner, party); } node = decNode; } else if (currentNode.Name == "leaf") { XmlNodeList parameterList = currentNode.ChildNodes; List <string> parameters = new List <string>(); foreach (XmlNode paramNode in parameterList) { parameters.Add(paramNode.InnerText); } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Check") { if (nodeAttributes["name"] != null) { string actionName = nodeAttributes["name"].Value; BTCheck checkNode = new BTCheck(); checkNode.Action = actionName; checkNode.Parameters = parameters; checkNode.MyAI = owner; checkNode.MyParty = party; node = checkNode; } } if (nodeAttributes["type"] != null && nodeAttributes["type"].Value == "Action") { if (nodeAttributes["name"] != null) { BTLeaf leafNode = (BTLeaf)System.Activator.CreateInstance(System.Type.GetType("BT" + nodeAttributes["name"].Value)); leafNode.Parameters = parameters; leafNode.MyAI = owner; leafNode.MyParty = party; node = leafNode; } } } return(node); }
public BTSequenceState(BTSequence node) : base(node) { this.status = node.m_status; this.idx = node._idx; }
protected override void Init() { // -------Prepare-------- // 1. Initialize parent base.Init (); // 2. Enable BT framework's log for debug, optional // BTConfiguration.ENABLE_LOG = true; // 3. Create root, usually it's a priority selector _root = new BTPrioritySelector(); // 4. Create the nodes for reuse later // Preconditions CheckInSight checkOrcInSight = new CheckInSight(sightForOrc, ORC_NAME); CheckInSight checkGoblinInFightDistance = new CheckInSight(fightDistance, GOBLIN_NAME); CheckInSight checkGoblinInSight = new CheckInSight(sightForGoblin, GOBLIN_NAME); // Actions BTParallel run = new BTParallel(BTParallel.ParallelFunction.Or); { run.AddChild(new DoRun(DESTINATION, speed)); run.AddChild(new PlayAnimation(RUN_ANIMATION)); } FindEscapeDestination findDestination = new FindEscapeDestination(ORC_NAME, DESTINATION, sightForOrc); FindToTargetDestination findToTargetDestination = new FindToTargetDestination(GOBLIN_NAME, DESTINATION, fightDistance * 0.9f); // -------Construct------- // 3.1 Escape node // "Escape" serves as a parallel node // "Or" means the parallel node ends when any of its children ends. BTParallel escape = new BTParallel(BTParallel.ParallelFunction.Or, checkOrcInSight); { escape.AddChild(findDestination); escape.AddChild(run); } _root.AddChild(escape); // Add node into root // 3.2 Fight node BTSequence fight = new BTSequence(checkGoblinInSight); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.Or); { parallel.AddChild(findToTargetDestination); parallel.AddChild(run); // Reuse Run } fight.AddChild(parallel); fight.AddChild(new PlayAnimation(FIGHT_ANIMATION, checkGoblinInFightDistance)); } _root.AddChild(fight); // 3.3 Idle node _root.AddChild(new PlayAnimation(IDLE_ANIMATION)); }
protected override void Init() { // -------Prepare-------- // 1. Initialize parent base.Init(); // 2. Enable BT framework's log for debug, optional // BTConfiguration.ENABLE_LOG = true; // 3. Create root, usually it's a priority selector _root = new BTPrioritySelector(); // 4. Create the nodes for reuse later // Preconditions CheckInSight checkOrcInSight = new CheckInSight(sightForOrc, ORC_NAME); CheckInSight checkGoblinInFightDistance = new CheckInSight(fightDistance, GOBLIN_NAME); CheckInSight checkGoblinInSight = new CheckInSight(sightForGoblin, GOBLIN_NAME); // Actions BTParallel run = new BTParallel(BTParallel.ParallelFunction.Or); { run.AddChild(new DoRun(DESTINATION, speed)); run.AddChild(new PlayAnimation(RUN_ANIMATION)); } FindEscapeDestination findDestination = new FindEscapeDestination(ORC_NAME, DESTINATION, sightForOrc); FindToTargetDestination findToTargetDestination = new FindToTargetDestination(GOBLIN_NAME, DESTINATION, fightDistance * 0.9f); // -------Construct------- // 3.1 Escape node // "Escape" serves as a parallel node // "Or" means the parallel node ends when any of its children ends. BTParallel escape = new BTParallel(BTParallel.ParallelFunction.Or, checkOrcInSight); { escape.AddChild(findDestination); escape.AddChild(run); } _root.AddChild(escape); // Add node into root // 3.2 Fight node BTSequence fight = new BTSequence(checkGoblinInSight); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.Or); { parallel.AddChild(findToTargetDestination); parallel.AddChild(run); // Reuse Run } fight.AddChild(parallel); fight.AddChild(new PlayAnimation(FIGHT_ANIMATION, checkGoblinInFightDistance)); } _root.AddChild(fight); // 3.3 Idle node _root.AddChild(new PlayAnimation(IDLE_ANIMATION)); }
public void Init() { // 条件 BaseCondiction.ExternalFunc IsDeadFun = () => { if (mMonster.mRoleData.mHp <= 0) { return(true); } else { return(false); } }; var Alive = new PreconditionNOT(IsDeadFun, "活"); var Dead = new Precondition(IsDeadFun, "死"); BaseCondiction.ExternalFunc targetFun = () => { Role targetRole = mMonster.mRoleData.GetTargetRole(); if (targetRole) { return(targetRole.mBuffSystem.EnableSelect()); } else { return(false); } }; var hasTarget = new Precondition(targetFun, "发现目标"); var hasNoTarget = new PreconditionNOT(targetFun, "无目标"); BaseCondiction.ExternalFunc AtkRangeFun = () => { Role targetRole = mMonster.mRoleData.GetTargetRole(); if (targetRole) { float dis = Vector3.Distance(targetRole.transform.position, mMonster.transform.position); if (dis <= mMonster.mSkillInfo.mAtkDistance) { return(true); } else { if (dis > 5)//脱离目标 { mMonster.mRoleData.SetTargetRole(-1); } } } return(false); }; var AtkRange = new Precondition(AtkRangeFun, "在攻击范围内"); var NoAtkRange = new PreconditionNOT(AtkRangeFun, "超出攻击范围"); //BaseCondiction.ExternalFunc HpFun = () => { if (mMonster.mRoleData.mHp <= 50) return true; else return false; }; //var HPLess = new Precondition(HpFun, "快死"); //var HPMore = new PreconditionNOT(HpFun, "健康"); BaseCondiction.ExternalFunc CanMoveFun = () => { return(mMonster.mBuffSystem.CanMove()); }; var canMove = new Precondition(CanMoveFun, "能移动"); var cantMove = new PreconditionNOT(CanMoveFun, "不能移动"); BaseCondiction.ExternalFunc CanAtkFun = () => { return(mMonster.mBuffSystem.CanAtk()); }; var canAtk = new Precondition(CanAtkFun, "能攻击"); var cantAtk = new PreconditionNOT(CanAtkFun, "不能攻击"); //BaseCondiction.ExternalFunc EnableSelectFun = () => //{ // Role targetRole = mMonster.mRoleData.GetTargetRole(); // if (targetRole) // { // return targetRole.mBuffSystem.EnableSelect(); // } // return false; //}; //var enableSelect = new Precondition(EnableSelectFun, "能选"); ////var disableSelect = new PreconditionNOT(EnableSelectFun, "不能选"); //BT Tree mRoot = new BTSelector(); mRoot.name = "Root"; mRoot.Activate(); BTSequence DeadSeq = new BTSequence(); { DeadSeq.AddChild(Dead); // 死亡Action DeadSeq.AddChild(new BTActionWait(5)); DeadSeq.AddChild(new ReviveAction(mMonster)); mRoot.AddChild(DeadSeq); } BTSelector AliveSel = new BTSelector(); BTSequence AliveSeq = new BTSequence(); { AliveSeq.AddChild(Alive); AliveSeq.AddChild(AliveSel); mRoot.AddChild(AliveSeq); } BTSequence followSubtree = new BTSequence(); { followSubtree.AddChild(canMove); followSubtree.AddChild(hasTarget); followSubtree.AddChild(NoAtkRange); //followSubtree.AddChild(HPMore); // 追击Action followSubtree.AddChild(new FollowAction(mMonster)); AliveSel.AddChild(followSubtree); } BTSequence atkSeq = new BTSequence(); { atkSeq.AddChild(canAtk); atkSeq.AddChild(hasTarget); atkSeq.AddChild(AtkRange); //atkSeq.AddChild(HPMore); // 攻击Action atkSeq.AddChild(new AttackAction(mMonster)); atkSeq.AddChild(new BTActionWaitRandom(2.0f, 3.0f)); AliveSel.AddChild(atkSeq); } BTSequence patrolSeq = new BTSequence(); { patrolSeq.AddChild(canMove); patrolSeq.AddChild(hasNoTarget); patrolSeq.AddChild(new BTActionWaitRandom(1.0f, 5.0f)); // 巡逻Action patrolSeq.AddChild(new PatrolAction(mMonster)); AliveSel.AddChild(patrolSeq); } BTSequence IdleSeq = new BTSequence(); { IdleSeq.AddChild(hasNoTarget); // 休息Action IdleSeq.AddChild(new IdleAction(mMonster)); AliveSel.AddChild(IdleSeq); } //BTSequence runAwaySeq = new BTSequence(); //{ // runAwaySeq.AddChild(canMove); // runAwaySeq.AddChild(hasTarget); // runAwaySeq.AddChild(HPLess); // // 逃跑Action // runAwaySeq.AddChild(new RunAwayAction(mMonster)); // AliveSel.AddChild(runAwaySeq); //} }
private void InitializeEnemyPhaseBehaviourTree() { // Returns fail when there are enemies. Success if no enemies found. BTAction BTAct_NoEnemyCheck = new BTAction( () => { // If there are not even one enemy. Nothing to do here. if (EnemyList.Count < 1) { return(BTStatus.Success); } return(BTStatus.Failure); } ); BTAction BTAct_EnemyPhaseStartAnimations = new BTAction( () => { if (EPdoneStartAnimation == false) { EventAnimationController.Instance.ExecutePhaseAnimation(GamePhase.EnemyPhase); EPdoneStartAnimation = true; return(BTStatus.Running); } else if (EventAnimationController.Instance.IsAnimating == false) { EPdoneStartAnimation = false; ControlAreaManager.Instance.SetControlBlockerEnabled(true); return(BTStatus.Success); } return(BTStatus.Running); } ); BTAction BTAct_MoveEnemyPieces = new BTAction( () => { EnemyPiece curEnemy = null; if (EPcurEnemyIndex < EnemyList.Count) { curEnemy = EnemyList[EPcurEnemyIndex]; } switch (curEnemy.TurnStatus) { case EnemyTurnStatus.Unprocessed: curEnemy.ExecuteTurn(); break; case EnemyTurnStatus.Running: return(BTStatus.Running); // Do nothing, just let it run. default: // Both processed and waiting, move on to the next EnemyPiece. EPcurEnemyIndex++; if (EPcurEnemyIndex >= EnemyList.Count) // If went through the whole thing once already. { EPcurEnemyIndex = 0; BoardScroller.Instance.FocusCameraToPos( DungeonManager.Instance.GridPosToWorldPos(GameManager.Instance.Player.PosX, GameManager.Instance.Player.PosY), 0.2f, Graph.InverseExponential); return(BTStatus.Success); } break; } return(BTStatus.Running); } ); BTAction BTAct_AttackPlayer = new BTAction( () => { EnemyPiece curEnemy = null; if (EPcurEnemyIndex < EnemyList.Count) { curEnemy = EnemyList[EPcurEnemyIndex]; } switch (curEnemy.TurnStatus) { case EnemyTurnStatus.Waiting: curEnemy.ExecuteTurn(); break; case EnemyTurnStatus.Running: return(BTStatus.Running); // Do nothing, just let it run. default: // Move on to the next one. Only search for those that are Waiting status. EPcurEnemyIndex++; if (EPcurEnemyIndex >= EnemyList.Count) // If went finish second pass. { return(BTStatus.Success); } break; } return(BTStatus.Running); } ); // Reduce the player's shield by 1 point after end of every enemy turn. BTAction BTAct_ReducePlayersShield = new BTAction( () => { Player.DeductShieldPoints(1); if (Player.TurnStatus == PlayerTurnStatus.Running) { return(BTStatus.Running); } else { EndEnemyPhase(); return(BTStatus.Success); } } ); // BT_Sequence only runs when there are enemy pieces. // Refer to BT_NullCheckSelector below. BTSequence BT_EnemyMovementSequence = new BTSequence(BTAct_MoveEnemyPieces, BTAct_AttackPlayer); // Root is Selector that checks for enemies. // If no enemies, immediately stops (BTAct_NoEnemyCheck returns success). BTSelector BT_NullCheckSelector = new BTSelector(BTAct_NoEnemyCheck, BT_EnemyMovementSequence); BTSequence BT_Root = new BTSequence(BTAct_EnemyPhaseStartAnimations, BT_NullCheckSelector, BTAct_ReducePlayersShield); mEnemyPhaseBehaviourTree = new BehaviourTree(BT_Root); }
public override BTNode Init() { base.Init(); animator = GetComponent <Animator>(); BTSelector root = new BTSelector(); BTActionDeath death = new BTActionDeath(gameObject); root.AddChild(death); //领地限制的分支,只能在该范围活动 BTConditionEvaluator evaluatorTerritory = new BTConditionEvaluator(BTLogic.And, false, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); evaluatorTerritory.AddConditional(new BTCheckWithinDistance(_database.transform, territoryDis, null, BTCheckWithinDistance.DataOpt.FixedPosition), true); BTSimpleParallel goHome = new BTSimpleParallel(); { goHome.SetPrimaryChild(new BTActionCharacterMove(_database.transform, speed, 0.1f, null, BTActionMove.DataOpt.FixedPosition, BTActionMove.UsageOpt.Position, BTDataReadOpt.ReadEveryTick)); goHome.AddChild(new BTActionPlayAnimation(animator, "Walk")); } evaluatorTerritory.child = goHome; root.AddChild(evaluatorTerritory); BTConditionEvaluator evaluatorTarget = new BTConditionEvaluator(BTLogic.And, true, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); evaluatorTarget.AddConditional(new BTCheckExistence(_database.transform, defendDis, "Player", BTCheckExistence.CheckOpt.CheckSphere)); //加一层组合,来判断进行哪个动作 BTSelector actionSelector = new BTSelector(); evaluatorTarget.child = actionSelector; //评估是否有碰撞 BTConditionEvaluator evaluatorCollision = new BTConditionEvaluator(BTLogic.And, true, BT.BTConditionEvaluator.ClearChildOpt.OnNotRunning); BTCheckCollision collision = new BTCheckCollision("Player", tolerance, BTCheckCollision.CheckOpt.RayCast); evaluatorCollision.AddConditional(collision); BTSequence attackSubtre = new BTSequence(); { attackSubtre.AddChild(new BTActionPlayAnimation(animator, "Attack")); } evaluatorCollision.child = attackSubtre; actionSelector.AddChild(evaluatorCollision); //没有碰撞则移动 BTSimpleParallel moveTo = new BTSimpleParallel(); { moveTo.SetPrimaryChild(new BTActionCharacterMove(_database.transform, speed, tolerance, target, BTDataReadOpt.ReadEveryTick)); moveTo.AddChild(new BTActionPlayAnimation(animator, "Walk")); } actionSelector.AddChild(moveTo); root.AddChild(evaluatorTarget); //Idle分支 BTActionPlayAnimation palyIdle = new BTActionPlayAnimation(animator, "Idle"); root.AddChild(palyIdle); return(root); }
private float speed; //スピード //初期化処理 void Start() { //Commandの生成 m_nockBackingCommand = this.gameObject.AddComponent <BTNockBackingCommand>(); m_dyingCommand = this.gameObject.AddComponent <BTDyingCommand>(); m_flownDamageWaitingCommand = this.gameObject.AddComponent <BTWaitingCommand>(); m_findingReactionCommand = this.gameObject.AddComponent <BTFindingReactionCommand>(); m_runningAwayCommand = this.gameObject.AddComponent <BTRunningAwayCommand>(); m_forwardSwingWaitingCommand = this.gameObject.AddComponent <BTWaitingCommand>(); m_shootingCommand = this.gameObject.AddComponent <BTShootingCommand>(); m_followThroughWaitingCommand = this.gameObject.AddComponent <BTWaitingCommand>(); m_wanderingWaitingCommand = this.gameObject.AddComponent <BTWaitingCommand>(); m_wanderingCommand = this.gameObject.AddComponent <BTWanderingCommand>(); //Conditionの生成 m_isFlownAttackedCondition = this.gameObject.AddComponent <BTIsFlownAttackedCondition>(); m_isDyingCondition = this.gameObject.AddComponent <BTIsDyingCondition>(); m_isFindingPlayerCondition = this.gameObject.AddComponent <BTIsFindingPlayerCondition>(); //Commandの初期化 m_nockBackingCommand.Initialize(this.gameObject); m_dyingCommand.Initialize(this.gameObject); m_flownDamageWaitingCommand.Initialize(0.1f); m_findingReactionCommand.Initialize(this.gameObject); m_runningAwayCommand.Initialize(this.gameObject); m_forwardSwingWaitingCommand.Initialize(1); m_shootingCommand.Initialize(this.gameObject); m_followThroughWaitingCommand.Initialize(1); m_wanderingWaitingCommand.Initialize(3); m_wanderingCommand.Initialize(this.gameObject); //Conditionの初期化 m_isFlownAttackedCondition.Initialize(this.gameObject); m_isDyingCondition.Initialize(this.gameObject); m_isFindingPlayerCondition.Initialize(this.gameObject); //Nodeの生成・初期化・連結 //third1 m_isDyingNode = new BTConditionToEnd(m_isDyingCondition); m_dyingNode = new BTActionNode(m_dyingCommand); m_flownDamageWaitingNode = new BTActionNode(m_flownDamageWaitingCommand); //third2 m_findingReactionNode = new BTActionNode(m_findingReactionCommand); m_runningAwayNode = new BTActionNode(m_runningAwayCommand); m_forwardSwingWaitingNode = new BTActionNode(m_forwardSwingWaitingCommand); m_shootingNode = new BTActionNode(m_shootingCommand); m_followThroughNode = new BTActionNode(m_followThroughWaitingCommand); //third3 m_wanderingNode = new BTActionNode(m_wanderingCommand); m_wanderingWaitingNode = new BTActionNode(m_wanderingWaitingCommand); //second1 m_nockBackingNode = new BTActionNode(m_nockBackingCommand); m_afterNockBackNode = new BTBoolSelector(m_dyingNode, m_flownDamageWaitingNode, m_isDyingNode); //second2 m_nockBackingNode = new BTActionNode(m_nockBackingCommand); m_afterNockBackNode = new BTBoolSelector(m_dyingNode, m_flownDamageWaitingNode, m_isDyingNode); //second3 m_isFindingPlayerNode = new BTConditionNotToEnd(m_isFindingPlayerCondition); List <BaseBTNode> attackFlow = new List <BaseBTNode>(); attackFlow.Add(m_runningAwayNode); attackFlow.Add(m_forwardSwingWaitingNode); attackFlow.Add(m_shootingNode); attackFlow.Add(m_followThroughNode); m_attackFlowingNode = new BTSequence(attackFlow); List <BaseBTNode> wanderFlow = new List <BaseBTNode>(); wanderFlow.Add(m_wanderingNode); wanderFlow.Add(m_wanderingWaitingNode); m_wanderFlowingNode = new BTSequence(wanderFlow); //first m_isFlownAttackedNode = new BTConditionNotToEnd(m_isFlownAttackedCondition); List <BaseBTNode> isFlownAttackedList = new List <BaseBTNode>(); isFlownAttackedList.Add(m_nockBackingNode); isFlownAttackedList.Add(m_afterNockBackNode); m_damageExpressionNode = new BTSequence(isFlownAttackedList); m_commonActionNode = new BTBoolSelector(m_attackFlowingNode, m_wanderFlowingNode, m_isFindingPlayerNode); //root m_rootNode = new BTTEandNTEBoolSelector(m_damageExpressionNode, m_commonActionNode, m_isFlownAttackedNode); status = GetComponent <EnemyStatus>(); status.SetEnemyType(EnemyType.Shooter); speed = 0; }
protected override void Init() { base.Init(); root = new BTPrioritySelector(); // 根节点首先是一个选择器 // 转移条件 MonsterCheckPlayerInRange playerInRange = new MonsterCheckPlayerInRange(checkPlayerRange, PLAYER_NAME); MonsterCheckPlayerInRange playerNotInRange = new MonsterCheckPlayerInRange(checkPlayerRange, PLAYER_NAME, true); // 行为节点 move = new MonsterMove(DESTINATION, moveSpeed); MonsterFindToTargetDestination findToTargetDestination = new MonsterFindToTargetDestination(PLAYER_NAME, PLAYERLOCATION, DESTINATION, ATKdistance); MonsterWait monsterWait = new MonsterWait(); // 怪兽攻击 MonsterAttack monsterAttack; if (myMonsterType == MonsterType.LongDistanceAttack) { monsterAttack = new MonsterLongDistanceAttacks(longDistanceATK); } else if (myMonsterType == MonsterType.MeleeAttack) { monsterAttack = new MonsterMeleeAttack(meleeATK); } else { monsterAttack = new MonsterAttack(meleeATK); // 先暂时为近战的攻击力 } MonsterRandomMoveDistance randomMoveDistance = new MonsterRandomMoveDistance(DESTINATION, moveX, moveZ); MonsterRotateToTarget monsterMoveRotate = new MonsterRotateToTarget(DESTINATION); MonsterRotateToTarget attackRotate = new MonsterRotateToTarget(PLAYERLOCATION); // 攻击 BTSequence attack = new BTSequence(playerInRange); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.Or); { parallel.AddChild(findToTargetDestination); // 先找到走到攻击目标的目的地 BTSequence rotateAndMove = new BTSequence(); { rotateAndMove.AddChild(monsterMoveRotate); rotateAndMove.AddChild(move); } parallel.AddChild(rotateAndMove); // 怪物朝着目的地移动 } attack.AddChild(parallel); attack.AddChild(attackRotate); // 怪物朝向玩家 attack.AddChild(monsterAttack); // 进行攻击 } root.AddChild(attack); // 随机巡逻 BTSequence randomMove = new BTSequence(playerNotInRange); { randomMove.AddChild(monsterWait); // 怪物静止几秒 BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.And); { parallel.AddChild(randomMoveDistance); // 随机找一个移动地点 BTSequence rotateAndMove = new BTSequence(); { rotateAndMove.AddChild(monsterMoveRotate); rotateAndMove.AddChild(move); } parallel.AddChild(rotateAndMove); // 怪物朝着目的地移动 } randomMove.AddChild(parallel); } root.AddChild(randomMove); }
private bool isPreHealthHalfDown; //前フレームに体力が半分を下回ったか // Use this for initialization void Start() { //Commandの生成 m_angryMotionCommand = gameObject.AddComponent <BTAngryMotionBossCommand>();; m_playerObserverCommand = gameObject.AddComponent <BTPlayerObserverBossCommand>(); m_inkSpewCommand = gameObject.AddComponent <BTInkSpewBossCommand>(); m_instanceEnemyCommand = gameObject.AddComponent <BTInstanceEnemyBossCommand>(); m_waitingCommand = gameObject.AddComponent <BTWaitingCommand>(); m_rotationAttackCommand = gameObject.AddComponent <BTRotationAttackBossCommand>(); m_crabScissorsCommand = gameObject.AddComponent <BTCrabScissorsBossCommand>(); m_momentMaulCommand = gameObject.AddComponent <BTMomentMaulBossCommand>(); m_separateContinuousAttackCommand = gameObject.AddComponent <BTSeparateContinuousAttackBossCommand>(); m_fireBallPreventingEscapeCommand = gameObject.AddComponent <BTFireBallPreventingEscapeBossCommand>(); m_waiting2Command = gameObject.AddComponent <BTWaitingCommand>(); m_dyingMotionCommand = gameObject.AddComponent <BTDyingMotionBossCommand>(); m_diedCommand = gameObject.AddComponent <BTDiedBossCommand>(); m_instanceEnemy2Command = gameObject.AddComponent <BTInstanceEnemyBossCommand>(); m_waiting3Command = gameObject.AddComponent <BTWaitingCommand>(); m_stompCommand = gameObject.AddComponent <BTStompBossCommand>(); m_upDownCrabScissorsCommand = gameObject.AddComponent <BTUpDownCrabScissorsBossCommand>(); m_seaWavyCommand = gameObject.AddComponent <BTSeaWavyBossCommand>(); m_meteoWithWaterGunCommand = gameObject.AddComponent <BTMeteoWithWaterGunBossCommand>(); m_waiting4Command = gameObject.AddComponent <BTWaitingCommand>(); //Conditionの生成 m_isHealthHalfDownCondition = gameObject.AddComponent <BTIsHealthHalfDownCondition>(); m_isDyingCondition = gameObject.AddComponent <BTIsDyingBossCondition>(); m_isAfterDyingCondition = gameObject.AddComponent <BTIsAfterDyingCondition>(); //Commandの初期化 m_angryMotionCommand.Initialize(this.gameObject); m_playerObserverCommand.Initialize(this.gameObject); m_inkSpewCommand.Initialize(this.gameObject); m_instanceEnemyCommand.Initialize(this.gameObject); m_waitingCommand.Initialize(3); m_rotationAttackCommand.Initialize(this.gameObject); m_crabScissorsCommand.Initialize(this.gameObject); m_momentMaulCommand.Initialize(this.gameObject); m_separateContinuousAttackCommand.Initialize(this.gameObject); m_fireBallPreventingEscapeCommand.Initialize(this.gameObject); m_waiting2Command.Initialize(0.1f); m_dyingMotionCommand.Initialize(this.gameObject); m_diedCommand.Initialize(this.gameObject); m_instanceEnemy2Command.Initialize(this.gameObject); m_waiting3Command.Initialize(2); m_stompCommand.Initialize(this.gameObject); m_upDownCrabScissorsCommand.Initialize(this.gameObject); m_seaWavyCommand.Initialize(this.gameObject); m_meteoWithWaterGunCommand.Initialize(this.gameObject); m_waiting4Command.Initialize(0.1f); //Conditionの初期化 m_isHealthHalfDownCondition.Initialize(this.gameObject); m_isDyingCondition.Initialize(this.gameObject); m_isAfterDyingCondition.Initialize(this.gameObject); //Nodeの生成・初期化・連結 //前半のBT //third1 m_rotationAttackNode = new BTActionNode(m_rotationAttackCommand); m_crabScissorsNode = new BTActionNode(m_crabScissorsCommand); m_momentMaulNode = new BTActionNode(m_momentMaulCommand); m_separateContinuousAttackNode = new BTActionNode(m_separateContinuousAttackCommand); m_fireBallPreventingEscapeNode = new BTActionNode(m_fireBallPreventingEscapeCommand); //second1 m_angryMotionNode = new BTActionNode(m_angryMotionCommand); m_playerObserverNode = new BTActionNode(m_playerObserverCommand); m_inkSpewNode = new BTActionNode(m_inkSpewCommand); //second2 m_instanceEnemyNode = new BTActionNode(m_instanceEnemyCommand); m_waitingNode = new BTActionNode(m_waitingCommand); List <BaseBTNode> randomAttack = new List <BaseBTNode>(); randomAttack.Add(m_rotationAttackNode); randomAttack.Add(m_crabScissorsNode); randomAttack.Add(m_momentMaulNode); randomAttack.Add(m_fireBallPreventingEscapeNode); m_randomAttackNode = new BTOnOffSelector(randomAttack); m_waiting2Node = new BTActionNode(m_waiting2Command); //first1 m_isHealthHalfDownNode = new BTConditionNotToEnd(m_isHealthHalfDownCondition); List <BaseBTNode> halfMotion = new List <BaseBTNode>(); halfMotion.Add(m_angryMotionNode); halfMotion.Add(m_playerObserverNode); halfMotion.Add(m_inkSpewNode); m_halfMotionNode = new BTSequence(halfMotion); List <BaseBTNode> commonAction = new List <BaseBTNode>(); commonAction.Add(m_instanceEnemyNode); commonAction.Add(m_waitingNode); commonAction.Add(m_randomAttackNode); commonAction.Add(m_waiting2Node); m_commonActionNode = new BTSequence(commonAction); //root m_rootNode = new BTTEandNTEBoolSelector(m_halfMotionNode, m_commonActionNode, m_isHealthHalfDownNode); //後半のBT //fourth m_stompNode = new BTActionNode(m_stompCommand); m_upDownCrabScissorsNode = new BTActionNode(m_upDownCrabScissorsCommand); m_seaWavyNode = new BTActionNode(m_seaWavyCommand); m_meteoWithWaterGunNode = new BTActionNode(m_meteoWithWaterGunCommand); //third1 List <BaseBTNode> newRandomAttack = new List <BaseBTNode>(); newRandomAttack.Add(m_stompNode); m_randomAttackNode2 = new BTOnOffSelector(randomAttack); //second1 m_isAfterDyingNode = new BTConditionToEnd(m_isAfterDyingCondition); m_dyingMotionNode = new BTActionNode(m_dyingMotionCommand); m_diedNode = new BTActionNode(m_diedCommand); //second2 m_instanceEnemyNode2 = new BTActionNode(m_instanceEnemy2Command); m_waiting3Node = new BTActionNode(m_waiting3Command); List <BaseBTNode> twoSelection = new List <BaseBTNode>(); twoSelection.Add(m_randomAttackNode); twoSelection.Add(m_randomAttackNode2); m_randomTwoSelectionAttack = new BTOnOffSelector(twoSelection); m_waiting4Node = new BTActionNode(m_waiting4Command); //first1 m_isDyingNode = new BTConditionNotToEnd(m_isDyingCondition); m_afterDyingNode = new BTBoolSelector(m_diedNode, m_dyingMotionNode, m_isAfterDyingNode); List <BaseBTNode> commonAction2 = new List <BaseBTNode>(); commonAction2.Add(m_instanceEnemyNode2); commonAction2.Add(m_waiting3Node); commonAction2.Add(m_randomAttackNode); commonAction2.Add(m_waiting4Node); m_commonActionNode2 = new BTSequence(commonAction2); //root m_rootNode2 = new BTTEandNTEBoolSelector(m_afterDyingNode, m_commonActionNode2, m_isDyingNode); status = GetComponent <BossStatus>(); movePosition = new Vector3[4]; lookAtPosition = new Vector3[4]; isHealthHalfDown = false; isPreHealthHalfDown = false; }
protected override void Init() { base.Init(); root = new BTPrioritySelector(); // 根节点首先是一个选择器 // 转移条件 // 远程攻击条件 MonsterCheckPlayerInRangeAndRandomAttack longAttack = new MonsterCheckPlayerInRangeAndRandomAttack(checkPlayerRange, PLAYER_NAME, true); // 进程攻击条件 MonsterCheckPlayerInRangeAndRandomAttack meleeAttack = new MonsterCheckPlayerInRangeAndRandomAttack(checkPlayerRange, PLAYER_NAME, false); // 静止条件 MonsterCheckPlayerInRange playerNotInRange = new MonsterCheckPlayerInRange(checkPlayerRange, PLAYER_NAME, true); // 行为节点 move = new MonsterMove(DESTINATION, moveSpeed); MonsterFindToTargetDestination findMeleeToTargetDestination = new MonsterFindToTargetDestination(PLAYER_NAME, PLAYERLOCATION, DESTINATION, ATKMeleeDistance); MonsterFindToTargetDestination findLongToTargetDestination = new MonsterFindToTargetDestination(PLAYER_NAME, PLAYERLOCATION, DESTINATION, ATKLongDistance); MonsterWait monsterWait = new MonsterWait(); MonsterLongDistanceAttacks monsterLongDistanceAttacks = new MonsterLongDistanceAttacks(longDistanceATK); MonsterMeleeAttack monsterMeleeAttack = new MonsterMeleeAttack(meleeATK); MonsterRotateToTarget monsterMoveRotate = new MonsterRotateToTarget(DESTINATION); MonsterRotateToTarget attackRotate = new MonsterRotateToTarget(PLAYERLOCATION); MonsterRandomMoveDistance randomMoveDistance = new MonsterRandomMoveDistance(DESTINATION, moveX, moveZ); // 随机巡逻(玩家不在攻击范围) BTSequence randomMove = new BTSequence(playerNotInRange); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.And); { parallel.AddChild(randomMoveDistance); // 随机找一个移动地点 BTSequence rotateAndMove = new BTSequence(); { rotateAndMove.AddChild(monsterMoveRotate); rotateAndMove.AddChild(move); } parallel.AddChild(rotateAndMove); // 怪物朝着目的地移动 } randomMove.AddChild(parallel); } root.AddChild(randomMove); // 进程攻击(一个随机数并且玩家在攻击范围内) BTSequence meleeattack = new BTSequence(meleeAttack); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.Or); { parallel.AddChild(findMeleeToTargetDestination); // 先找到走到攻击目标的目的地 BTSequence rotateAndMove = new BTSequence(); { rotateAndMove.AddChild(monsterMoveRotate); rotateAndMove.AddChild(move); } parallel.AddChild(rotateAndMove); // 怪物朝着目的地移动 } meleeattack.AddChild(parallel); meleeattack.AddChild(attackRotate); // 怪物朝向玩家 meleeattack.AddChild(monsterMeleeAttack); // 进行攻击 } root.AddChild(meleeattack); // 远程攻击(一个随机数并且玩家在攻击范围内) BTSequence longattack = new BTSequence(longAttack); { BTParallel parallel = new BTParallel(BTParallel.ParallelFunction.Or); { parallel.AddChild(findLongToTargetDestination); // 先找到走到攻击目标的目的地 BTSequence rotateAndMove = new BTSequence(); { rotateAndMove.AddChild(monsterMoveRotate); rotateAndMove.AddChild(move); } parallel.AddChild(rotateAndMove); // 怪物朝着目的地移动 } longattack.AddChild(parallel); longattack.AddChild(attackRotate); // 怪物朝向玩家 longattack.AddChild(monsterLongDistanceAttacks); // 进行攻击 } root.AddChild(longattack); }