private void SelTarget() { WarServerNpcMgr npcMgr = WarServerManager.Instance.npcMgr; List <ServerLifeNpc> buildList = npcMgr.GetBuildByType(myHero.Camp, BuildNPCType.Tower); if (buildList == null || buildList.Count == 0) { ConsoleEx.DebugError("no tower find "); } int len = buildList.Count; float minDis = Mathf.Infinity; for (int i = 0; i < len; i++) { if (buildList[i].IsAlive) { float dis = AITools.GetSqrDis(mTrans.position, buildList[i].transform.position); if (dis < minDis) { minDis = dis; target = buildList[i]; } } } mTargetTrans = target.transform; targetPos = target.transform.forward * target.data.configData.seekRange * -1; distance = myHero.data.configData.radius + target.data.configData.radius + 2.0f; }
// cast a ray between startPosition and targetPosition. Return true if a defensive object was hit private bool rayCollision(Vector3 startPosition, Vector3 targetPosition, out RaycastHit hit) { startPosition.y = 1; targetPosition.y = 1; float dis = AITools.GetSqrDis(this.transform.position, target.Value.transform.position); if (dis <= 0) { dis = 1.0f; } if (avoidDefeneUnits && Physics.Raycast(startPosition, targetPosition - startPosition, out hit, dis)) { ServerLifeNpc npc = null; if ((npc = hit.collider.GetComponent <ServerLifeNpc>()) != null) { return((npc.Camp == myHero.Camp) && (npc.UniqueID != myHero.UniqueID) && (npc.ATKRange == myHero.ATKRange)); } } hit = new RaycastHit(); return(false); }
public override TaskStatus OnUpdate() { if (myHero.mAnimState.canMove) { pathFind.destination = mTargetTrans.position; } if (pathFind != null && !pathFind.enabled) { pathFind.enabled = true; } if (myHero.mAnimState.STATE != NpcAnimState.Run) { myHero.SendAnimMsg(WarMsg_Type.Running); } if (AITools.IsInRange(mTrans.position, 1, mTargetTrans.position)) { myHero.SendAnimMsg(WarMsg_Type.Stand); pathFind.enabled = false; myHero.data.btData.atkerID = 0; myHero.data.btData.IsInBattle = false; myHero.data.btData.btStatus = NPCBattle_Status.RestForBlood; return(TaskStatus.Success); } return(TaskStatus.Running); }
public override TaskStatus OnUpdate() { CAMP enemyCamp = CAMP.None; if (myHero.Camp == CAMP.Enemy) { enemyCamp = CAMP.Player; } else if (myHero.Camp == CAMP.Player) { enemyCamp = CAMP.Enemy; } enemy = WarServerManager.Instance.realServer.monitor.CharactorPool.GetHeroList(enemyCamp); if (enemy == null || enemy.Count == 0) { return(TaskStatus.Failure); } // 范围内有人,返回失败 for (int i = 0; i < enemy.Count; i++) { if (AITools.IsInRange(mTransform.position, seekRange, enemy[i].transform)) { return(TaskStatus.Success); } } return(TaskStatus.Failure); }
public override TaskStatus OnUpdate() { if (!bInitFinish) { InitData(); return(TaskStatus.Running); } if (targets == null || targets.Count == 0) { if (npc.outLog) { ConsoleEx.DebugError("all the emermy is dead"); } return(TaskStatus.Failure); } npc.data.btData.atkerID = 0; npc.data.btData.IsInBattle = false; //如果跑到最后一个目标点,赢了 if (index.Value >= targets.Count) { // param.cmdType = WarMsg_Type.Idle; // param.Sender = npc.UniqueID; // param.Receiver = npc.UniqueID; // npc.SendMsg (npc.UniqueID, param); npc.SendAnimMsg(WarMsg_Type.Stand); return(TaskStatus.Success); } pathFind.speed = npc.data.configData.speed; if (npc.mAnimState.canMove) { if (!pathFind.enabled) { pathFind.enabled = true; } if (pathFind != null && mTargetTrans != null) { pathFind.destination = mTargetTrans.position; } } //如果跑到了当前位置,或者当前目标死亡,切换下一个目标,返回true if (AITools.IsInRange(mTrans.position, 2, mTargetTrans.position) || !targets[index.Value].IsAlive) { index.Value++; } if (npc.mAnimState.STATE != NpcAnimState.Run) { npc.SendAnimMsg(WarMsg_Type.Running); } return(TaskStatus.Running); }
public override TaskStatus OnUpdate() { //如果在范围内,返回成功 if (AITools.IsInRange(this.transform.position, atkRange, target.Value.transform.position)) { return(TaskStatus.Success); } return(TaskStatus.Failure); }
private void SelTarget() { //自家塔 List <ServerLifeNpc> mySpring = WarServerManager.Instance.npcMgr.GetBuildByType(myHero.Camp, BuildNPCType.Tower); if (mySpring != null && mySpring.Count > 0) { moveTarget = AITools.GetNeareastNPC(mTran.position, mySpring.ToArray()); } }
public override TaskStatus OnUpdate() { //如果在范围内,返回成功 if (AITools.IsInRange(this.transform.position, fleetofollowRange, leader.transform.position)) { return(TaskStatus.Success); } return(TaskStatus.Failure); }
private void SelTarget() { NeHeQiaoNpcMgr npcMgr = WarServerManager.Instance.npcMgr as NeHeQiaoNpcMgr; //自家泉水 if (myHero.Camp == CAMP.Player && npcMgr.SelfSpring != null) { npcList.Add(npcMgr.SelfSpring); } else if (myHero.Camp == CAMP.Enemy && npcMgr.EnemySpring != null) { npcList.Add(npcMgr.EnemySpring); } //公共泉水 if (npcMgr.NeutralSpring != null) { npcList.Add(npcMgr.NeutralSpring); } //所有道具 List <ServerNPC> allProp = WarServerManager.Instance.npcMgr.GetNPCByType(LifeNPCType.Prop, CAMP.None); if (allProp != null && allProp.Count > 0) { npcList.AddRange(allProp.ToArray()); } //得到距离自己最近的 ServerNPC npcTarget = null; if (npcList.Count > 0) { float minDis = Mathf.Infinity; for (int i = 0; i < npcList.Count; i++) { float distance = AITools.GetSqrDis(this.transform.position, npcList [i].transform.position); if (distance < minDis) { minDis = distance; npcTarget = npcList [i]; } } } target.Value = npcTarget; mTrans = myHero.transform; mTargetTrans = target.Value.transform; }
public override TaskStatus OnUpdate() { //自己阵营所有的npc List <ServerLifeNpc> selfNpcs = npcMgr.GetLifeNPCListByCamp(npc.Camp); //自己身后六米的地方 Vector3 dir = Vector3.Normalize(mTargetTrans.position - mTrans.position) * 10; Vector3 fromPos = mTrans.position + dir; List <ServerLifeNpc> nearNpcs = AITools.GetAllNPCInRange(fromPos, 4, selfNpcs.ToArray()); if (nearNpcs != null && nearNpcs.Count > 0) { return(TaskStatus.Success); } return(TaskStatus.Failure); }
public override TaskStatus OnUpdate() { //如果自己单独作战,对面敌人大于1,并且不在塔下,返回成功 List <ServerLifeNpc> heros = AITools.GetAllNPCInRange(mTrans.position, seekRange, teamList); if (heros.Count == 1 && !IsUnderTower()) { List <ServerLifeNpc> enemys = AITools.GetAllNPCInRange(mTrans.position, seekRange, enemyList); if (enemys.Count >= 2) { npc.data.btData.btStatus = NPCBattle_Status.EscapeToDef; return(TaskStatus.Success); } } return(TaskStatus.Failure); }
public override TaskStatus OnUpdate() { if (enemy == null || enemy.Count == 0) { return(TaskStatus.Success); } // 范围内有人,返回失败 for (int i = 0; i < enemy.Count; i++) { if (enemy[i].IsAlive && AITools.IsInRange(mTargetTrans.position, seekRange + enemy[i].data.configData.radius, enemy[i].transform)) { return(TaskStatus.Failure); } } return(TaskStatus.Success); }
public override TaskStatus OnUpdate() { //如果建筑不能移动, if (npc.data.configData.moveable == Moveable.BeStatic) { return(TaskStatus.Success); } //如果对方死了,返回失败 if (!target.Value.IsAlive) { return(TaskStatus.Failure); } //如果进入技能范围,返回true if (AITools.IsInRange(mTrans.position, seekRange, mTargetTrans.position)) { pathFind.enabled = false; return(TaskStatus.Success); } if (!pathFind.enabled) { pathFind.enabled = true; } if (npc.mAnimState.canMove) { pathFind.destination = target.Value.transform.position; } if (npc.mAnimState.STATE != NpcAnimState.Run) { // param.cmdType = WarMsg_Type.Running; // param.Sender = npc.UniqueID; // param.Receiver = npc.UniqueID; // npc.SendMsg (npc.UniqueID, param); npc.SendAnimMsg(WarMsg_Type.Running); } return(TaskStatus.Running); }
public override TaskStatus OnUpdate() { List <ServerLifeNpc> tower = npcMgr.GetBuildByType(npc.Camp, BuildNPCType.Tower); if (tower == null || tower.Count == 0) { return(TaskStatus.Success); } // 范围内有人,返回失败 for (int i = 0; i < tower.Count; i++) { if (tower[i].IsAlive && AITools.IsInRange(mTransform.position, distance + tower[i].data.configData.radius, tower[i].transform)) { return(TaskStatus.Success); } } return(TaskStatus.Failure); }
public override TaskStatus OnUpdate() { if (tower == null || tower.Count == 0) { return(TaskStatus.Failure); } //在塔下。返回成功 for (int i = 0; i < tower.Count; i++) { float seekRange = tower[i].ATKRange + tower[i].data.configData.radius + npc.data.configData.radius + 2; if (tower[i].IsAlive && AITools.IsInRange(mTransform.position, seekRange, tower[i].transform)) { targetTower.Value = tower[i]; return(TaskStatus.Success); } } return(TaskStatus.Failure); }
public override TaskStatus OnUpdate() { List <ServerLifeNpc> soldiers = WarServerManager.Instance.npcMgr.GetLifeNPCByType(LifeNPCType.Soldier, npc.Camp); if (soldiers == null || soldiers.Count == 0) { return(TaskStatus.Failure); } // 范围内有人,返回失败 for (int i = 0; i < soldiers.Count; i++) { if (soldiers[i].IsAlive && AITools.IsInRange(mTransform.position, seekRange, soldiers[ i].transform)) { return(TaskStatus.Success); } } return(TaskStatus.Failure); }
bool IsUnderTower() { towers = WarServerManager.Instance.npcMgr.GetBuildByType(npc.Camp, BuildNPCType.Tower); if (towers == null || towers.Count == 0) { return(false); } ServerLifeNpc nearTower = AITools.GetNeareastNPC(mTrans.position, towers.ToArray()); if (nearTower != null) { // 塔后面 seekrange一半的地方以内 Vector3 targetPos = nearTower.transform.forward * nearTower.data.configData.seekRange * -1; if (AITools.IsInRange(mTrans.position, nearTower.data.configData.seekRange * 0.5f, targetPos)) { return(true); } } return(false); }
//往家里跑 public override TaskStatus OnUpdate() { myHero.data.btData.btStatus = NPCBattle_Status.Fleeing; //如果跑到了,返回成功 if (AITools.IsInRange(mTran.position, 3, mTargetTran.position)) { if (pathFind != null && pathFind.enabled) { pathFind.enabled = false; } myHero.data.btData.btStatus = NPCBattle_Status.None; fleeTarget.Value = null; myHero.data.btData.atkerID = 0; myHero.data.btData.IsInBattle = false; return(TaskStatus.Success); } if (pathFind != null && !pathFind.enabled) { pathFind.enabled = true; } if (myHero.mAnimState.canMove) { pathFind.destination = mTargetTran.position; } if (myHero.mAnimState.STATE != NpcAnimState.Run) { myHero.SendAnimMsg(WarMsg_Type.Running); } return(TaskStatus.Running); }
public override TaskStatus OnUpdate() { if (target == null) { SelTarget(); return(TaskStatus.Running); } //跑到塔下了 if (AITools.IsInRange(mTrans.position, distance, targetPos)) { myHero.SendAnimMsg(WarMsg_Type.Stand); myHero.data.btData.btStatus = NPCBattle_Status.None; pathFind.enabled = false; return(TaskStatus.Success); } if (pathFind != null && !pathFind.enabled) { pathFind.enabled = true; } if (myHero.mAnimState.STATE != NpcAnimState.Run) { myHero.SendAnimMsg(WarMsg_Type.Running); } if (myHero.mAnimState.canMove) { pathFind.destination = targetPos; } return(TaskStatus.Running); }
/// <summary> /// 检测伤害技能能否释放, /// 回血,恢复之类的技能不做检测 /// /// 判定顺序是: /// 0. 判定技能的类型 /// 1. 判定是否是相同的阵营 /// 2. 判定施法者的状态 /// 3. 判定目标是什么类型的NPC(比如建筑物,英雄。。。) /// 3. 判定施法的距离 /// 5. 目标的状态 /// /// </summary> /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns> public bool canCast(ServerNPC caster, ServerNPC target, RtSkData rtOne, bool ignoreDis = false) { bool can = true; #if DEBUG Utils.Assert(caster == null, "Can't know whether can cast skill unless caster isn't null."); Utils.Assert(target == null, "Can't know whether can cast skill unless target isn't null."); Utils.Assert(rtOne == null, "Can't know whether can cast skill unless runtime skill isn't null"); #endif SkillConfigData skillCfg = rtOne.skillCfg; /// 0. 判定技能的类型 can = skillCfg.DamageType == 0; if (can == false) { return(can); } /// 1.判定是否是相同的阵营 can = caster.Camp != target.Camp; if (can == false) { return(can); } /// 2. 判定施法者的状态 //只有LifeNPC才检查施法者的状态 ServerLifeNpc castlife = caster as ServerLifeNpc; if (castlife != null) { if (skillCfg.CasterStatusReject.AnySame(castlife.curStatus)) { //不可施法 can = false; } } if (can == false) { return(can); } /// 3. 判定目标是什么类型的NPC LifeNPCType type = skillCfg.TargetType.toPositive(); can = type.check(target.data.configData.type); if (can == false) { return(can); } /// 4. 判定施法的距离 if (ignoreDis == false) { can = AITools.IsInRange(caster.transform.position, skillCfg.Distance, target.transform); if (can == false) { return(can); } } /// 5. 目标的状态 ServerLifeNpc targetLife = target as ServerLifeNpc; if (targetLife != null) { if (targetLife.curStatus.AnySame(skillCfg.TargetStatusReject)) { //不可施法 can = false; } } return(can); }
public override bool Update(GameTime CurrTime) { int nCtr, nBestTargetID = -1, nBestAvoidID = -1; float nBestTargetDist = 0, nBestAvoidDist = 0, nCurrDist, nAvoidDir, nTargetDir; Vector2 vNewPos; List <PhysicalObject> aTargetList = cObjMgr[cnTargetGroupID]; List <PhysicalObject> aAvoidList = cObjMgr[cnAvoidGroupID]; base.Update(CurrTime); if (cnHealth <= 0) { //This enemy is dead :( //Should fire off some explosion particles return(false); } cTarget = null; cAvoid = null; //Find a target to track for (nCtr = 0; nCtr < aTargetList.Count; nCtr++) { nCurrDist = MGMath.SquaredDistanceBetweenPoints(CenterPoint, aTargetList[nCtr].CenterPoint); if (nBestTargetID == -1) //No target picked { nBestTargetID = nCtr; nBestTargetDist = nCurrDist; cTarget = aTargetList[nCtr]; } else if (nCurrDist < nBestTargetDist) { nBestTargetID = nCtr; nBestTargetDist = nCurrDist; cTarget = aTargetList[nCtr]; } } for (nCtr = 0; nCtr < aAvoidList.Count; nCtr += 1) { nCurrDist = MGMath.SquaredDistanceBetweenPoints(CenterPoint, aAvoidList[nCtr].CenterPoint); if (nBestAvoidID == -1) //No target picked { nBestAvoidID = nCtr; nBestAvoidDist = nCurrDist; cAvoid = aAvoidList[nCtr]; } else if (nCurrDist < nBestAvoidDist) { nBestAvoidID = nCtr; nBestAvoidDist = nCurrDist; cAvoid = aAvoidList[nCtr]; } } if (nBestAvoidDist > cnMaxStrafeDist * cnMaxStrafeDist) { //Thing to avoid is too far away to worry about nBestAvoidID = -1; cAvoid = null; } if (nBestTargetID != -1) //Found a valid target, attack it { if (nBestTargetDist > (cnMaxStrafeDist * cnMaxStrafeDist)) { if (cnLastMove != 1) { cDevConsole?.AddText("Move closer"); } cnLastMove = 1; //Too far away to strafe, move closer nTargetDir = AITools.SteerTowardTarget(CenterPoint, aTargetList[nBestTargetID].CenterPoint, ObjectRotation, cnMaxTurn); } else if (nBestTargetDist < cnMinStrafeDist * cnMinStrafeDist) { if (cnLastMove != 2) { cDevConsole?.AddText("Back away"); } cnLastMove = 2; //Too close, steer away from target nTargetDir = AITools.SteerAwayFromTarget(CenterPoint, aTargetList[nBestTargetID].CenterPoint, ObjectRotation, cnMaxTurn); } else //Close enough, strafe around the target { if (cnLastMove != 3) { cDevConsole?.AddText("Strafe"); } cnLastMove = 3; nTargetDir = AITools.SteerToCircleTarget(CenterPoint, aTargetList[nBestTargetID].CenterPoint, ObjectRotation, cnMaxTurn, cbStrafeCW); } } else { nTargetDir = 0; } if (nBestAvoidID != -1) { nAvoidDir = AITools.SteerAwayFromTarget(CenterPoint, aAvoidList[nBestAvoidID].CenterPoint, ObjectRotation, cnMaxTurn); } else { nAvoidDir = 0; } if (cnTargetGroupID != -1) { if ((nBestAvoidID != -1) && (nBestAvoidDist < nBestTargetDist)) { //Thing to avoid is closer than the target, it gets priority nCurrDist = (0.75f * nAvoidDir) + (0.25f * nTargetDir); } else { //Target is closer, go for the kill nCurrDist = nTargetDir; } } else { //No target so just avoid? nCurrDist = nAvoidDir; } //Set the new movement direction, but don't change the speed SetMovement(nCurrDist, cnMaxSpeed); //Apply current speed vNewPos = CenterPoint; vNewPos.X += cvCurrSpeed.X; vNewPos.Y += cvCurrSpeed.Y; CenterPoint = vNewPos; if (ctHitFlashUntil > CurrTime.TotalGameTime.TotalMilliseconds) { //Flash red when being hit this.TintColor = Color.Red; } else { //Normal condition is white, for no tint this.TintColor = cclrNormalColor; } //Return True to keep this alive, false to have it removed return(true); }
public override bool Update(GameTime CurrTime) { Vector2 vNewPos; int nCtr, nBestTargetID = -1; float nBestTargetDist = 0, nCurrDist; List <PhysicalObject> aTargetList = cObjMgr[cnTargetGroupID]; bool bRetVal = true; base.Update(CurrTime); if (ctCreated == -1) //Just created, mark the time { ctCreated = CurrTime.TotalGameTime.TotalMilliseconds; } switch (ceProjType) { case eProjectileType_t.Tracking: //Find a target to track for (nCtr = 0; nCtr < aTargetList.Count; nCtr++) { nCurrDist = MGMath.SquaredDistanceBetweenPoints(CenterPoint, aTargetList[nCtr].CenterPoint); if (nBestTargetID == -1) //No target picked { nBestTargetID = nCtr; nBestTargetDist = nCurrDist; } else if (nCurrDist < nBestTargetDist) { nBestTargetID = nCtr; nBestTargetDist = nCurrDist; } } if (nBestTargetID != -1) //Found a valid target, steer toward it { nCurrDist = AITools.SteerTowardTarget(CenterPoint, aTargetList[nBestTargetID].CenterPoint, ObjectRotation, cnMaxTurn); //Set the new movement direction, but don't change the speed SetMovement(nCurrDist, cnMaxSpeed); } if (CurrTime.TotalGameTime.TotalMilliseconds - ctCreated > ctTimeToLive) { //Lived its full life, time to pop bRetVal = false; } break; case eProjectileType_t.Straight: default: //No logic, just flies straight if (cGraphDev.Viewport.Width < CenterPoint.X + Width) //remove it when off screen { bRetVal = false; } if (cGraphDev.Viewport.Height < CenterPoint.Y + Height) //remove it when off screen { bRetVal = false; } if (CenterPoint.X < -1 * Width) { bRetVal = false; } if (CenterPoint.Y < -1 * Height) { bRetVal = false; } break; } //Look for collisions with all possible targets foreach (PhysicalObject CurrObj in aTargetList) { if (CurrObj.TestCollision(this) == true) { //Hit a target! (tell it that it was hit) CurrObj.ReportCollision(CurrTime, this); bRetVal = false; break; } } //Apply the current speed vNewPos = CenterPoint; vNewPos.X += Speed.X; vNewPos.Y += Speed.Y; CenterPoint = vNewPos; if ((ParticleHandler != null) && (bRetVal == false)) { //Missile is expiring, throw some particles for (nCtr = 0; nCtr < 10; nCtr++) { ParticleHandler.AddParticle(new DustParticle(CenterPoint, Rand, cGraphDev, cImgAtlas, "spaceEffects_008.png")); } } //Return True to keep this alive, false to have it removed return(bRetVal); }
// Move towards the destination. Return success once we have reached the destination. Return failure if the destination has respawned and we no longer should be seeking it. // Will return running if we are currently seeking public override TaskStatus OnUpdate() { myHero.data.btData.btStatus = NPCBattle_Status.Seeking; if (myHero.data.configData.moveable == Moveable.BeStatic) { return(TaskStatus.Success); } if (!target.Value.IsAlive) { return(TaskStatus.Failure); } if (!navMeshAgent.enabled) { navMeshAgent.enabled = true; } if (myHero.mAnimState.canMove && myHero.mAnimState.STATE != NpcAnimState.Run) { // param.cmdType = WarMsg_Type.Running; // param.Sender = myHero.UniqueID; // param.Receiver = myHero.UniqueID; // myHero.SendMsg (myHero.UniqueID, param); myHero.SendAnimMsg(WarMsg_Type.Running); } // use the nav agent's destination position if we are on an alternate path or the target is null. We are using an alternate path if the previous path would have collided with // an object on defense. target will be null when we are seeking a position specified by the position variable var targetPosition = (alternatePath || target.Value == null ? navMeshAgent.destination : tgtPos); targetPosition.y = 1; // ignore y // we can only arrive if the path isn't pending var thisPosition = transform.position; thisPosition.y = targetPosition.y; // If the magnitude is less than the arrive magnitude then we have arrived at the destination if (AITools.IsInRange(thisPosition, myHero.ATKRange + myHero.data.configData.radius, navMeshAgent.destination)) { // If we arrived from an alternate path then switch back to the regular path if (alternatePath) { alternatePath = false; targetPosition = tgtPos; } else { // return success if we don't need to rotate to the target or we are already at the target's rotation // if (!rotateToTarget || transform.rotation == target.Value.transform.rotation) { // return TaskStatus.Success; // } return(TaskStatus.Success); // not done yet. still need to rotate // transform.rotation = Quaternion.RotateTowards(transform.rotation, target.Value.transform.rotation, rotationSpeed.Value * Time.deltaTime); } } // fail if the target moved too quickly in one frame. This happens after the target has been caught and respawns // float distance; // if (prevMagnitude * 2 < (distance = Vector3.SqrMagnitude(thisPosition - targetPosition))) { // return TaskStatus.Failure; // } // prevMagnitude = distance; // try not to head directly for a defensive object if (avoidDefeneUnits && (rayCollision(transform.position - transform.right * 1, targetPosition, out hit) || rayCollision(transform.position + transform.right * 1, targetPosition, out hit))) { // looks like an object is within the path. Avoid the object by setting a new destination towards the right of the object that we would have hit hitPoint = hit.point + transform.right * 3; // hitPoint.y = transform.position.y; hitPoint.y = 1; if (myHero.mAnimState.canMove) { navMeshAgent.destination = hitPoint; } // The avoid object may still be in the way even though we moved to the right of the object. If this is the case then move to the left and hope that works if (rayCollision(transform.position, navMeshAgent.destination, out hit)) { hitPoint = hit.point - transform.right * 4; // hitPoint.y = transform.position.y; hitPoint.y = 1; if (myHero.mAnimState.canMove) { navMeshAgent.destination = hitPoint; } } // remember that we are taking an alternate path to prevent the agent from jittering back and forth alternatePath = true; // var thisPosition = transform.position; // thisPosition.y = hitPoint.y; // prevMagnitude = Vector3.SqrMagnitude(thisPosition - hitPoint); } else if (navMeshAgent.destination != targetPosition) { // the target position has changed since we last set the destination. Update the destination // if (myHero.playHero.CanMove) if (myHero.mAnimState.canMove) { navMeshAgent.destination = targetPosition; } } return(TaskStatus.Running); }
public override TaskStatus OnUpdate() { if (!InitFinish) { InitData(); return(TaskStatus.Running); } InitData(); if (enermys == null || enermys.Count == 0) { return(TaskStatus.Failure); } //如果范围内有敌方敌人, List <ServerLifeNpc> list = AITools.GetAllNPCInRange(mTrans.position, seekRange, enermys.ToArray()); if (list != null && list.Count > 0) { ServerLifeNpc newTarget = null; //判断有没有攻击目标 IEnumerable <ServerNPC> enemyTargets = hero.FindAtkTarget(Sight.NearSight); if (enemyTargets != null && enemyTargets.Count <ServerNPC> () > 0) { newTarget = enemyTargets.ElementAt <ServerNPC> (0) as ServerLifeNpc; } else { enemyTargets = hero.FindAtkTarget(); if (enemyTargets != null && enemyTargets.Count <ServerNPC> () > 0) { newTarget = enemyTargets.ElementAt <ServerNPC> (0) as ServerLifeNpc; } } if (newTarget != null && newTarget.IsAlive) { //如果目标是建筑 if (newTarget.data.configData.type == LifeNPCType.Build) { //如果攻击目标是基地,判断三路是否有一路已经被破了,如果有一路被破了,才能打基地 if (newTarget.data.configData.bldType == BuildNPCType.Base) { bool canAtk = false; for (int i = 0; i < 3; i++) { //get all the tower on the way List <ServerLifeNpc> bldWay = WarServerManager.Instance.npcMgr.GetBuildByWay(newTarget.Camp, (BATTLE_WAY)i, false); if (bldWay != null && bldWay.Count > 0) { List <ServerLifeNpc> aliveBld = WarServerManager.Instance.npcMgr.GetBuildByWay(newTarget.Camp, (BATTLE_WAY)i, true); if (aliveBld != null && aliveBld.Count == 0) { canAtk = true; break; } } } if (canAtk) { target.Value = newTarget; return(TaskStatus.Success); } } //如果不是基地,判断前一个是否还活着,如果 else { // 得到当前这一路的所有活着的建筑 List <ServerLifeNpc> bldWay = WarServerManager.Instance.npcMgr.GetBuildByWay(newTarget.Camp, newTarget.dataInScene.way, true); if (bldWay != null && bldWay.Count > 0) { //检查活着的建筑里,有没有前一个建筑 bool canAtk = true; for (int i = 0; i < bldWay.Count; i++) { if (bldWay [i].dataInScene.index == newTarget.dataInScene.index - 1) { canAtk = false; break; } } if (canAtk) { target.Value = newTarget; return(TaskStatus.Success); } } } } else { target.Value = newTarget; return(TaskStatus.Success); } } } return(TaskStatus.Failure); }