public void Loop() { if (!enabled || !gameObject.activeSelf) { return; } if (!unit.enabled) { unit.OnEnable(); unit.ChangeAgentType(unit._baseData.eAgentType == EAgentType.ingoreObstacle? EAgentType.ingoreObstacle : EAgentType.astar); unit.agent.TargetPos = unit._defaultTargetPos; } CalculateEnemies(); TestAgent agent = null; FP tagetDstSqr = FP.MaxValue; if (_targetId >= 0) { agent = _testPathFinding.GetAgent(_targetId); if (agent != null) { tagetDstSqr = (agent.unit.position - unit.position).sqrMagnitude; } } for (int i = 0; i < _listEnemyAgents.Count; i++) { FP trueRange = attackRange + _listEnemyAgents[i].colliderRadius; FP dstSqr = (_listEnemyAgents[i].position - unit.position).sqrMagnitude; if (dstSqr < trueRange * trueRange) //in attackage range { if (unit.AgentType != EAgentType.none) { unit.SetNewTargetPos(_listEnemyAgents[i].position);////////////////////////// unit.stopMoving = true; unit._nextCheckActionTime = 0; unit._frameOffset = 20; _targetId = _listEnemyAgents[i].baseData.id; } break; } if (_targetId >= 0 && dstSqr >= tagetDstSqr - GridMap.GetNodeSize() * GridMap.GetNodeSize() && _targetId != unit.Id) { if (agent != null && unit.CanSetTargetPos(agent.unit.position)) { break; } } if (unit.SetNewTargetPos(_listEnemyAgents[i].position)) { int idx1 = unit.map.GetGridNodeId(unit.NewTargetPos); int idx2 = unit.map.GetGridNodeId(unit.targetPos); if (idx1 != idx2) { unit.stopMoving = false; } _targetId = _listEnemyAgents[i].baseData.id; break; } } if (_listEnemyAgents.Count == 0 || _targetId == 0) { TSVector targetPos = CustomMath.Vector3ToTsvec(_testPathFinding.destObj[unit.playerId].transform.position); // unit.ChangeAgentType(EAgentType.flowFiled); if ((targetPos - unit.position).sqrMagnitude > GridMap._checkDeltaDstSqr) { unit.stopMoving = false; } if (unit.NewTargetPos == TSVector.MinValue || unit.NewTargetPos == TSVector.MaxValue || _targetId == 0) // || (unit.NewTargetPos - unit.position).sqrMagnitude<unit.neighbourRadius*unit.neighbourRadius*225/100) { unit.SetNewTargetPos(targetPos); } //unit.agent.TargetPos = unit._defaultTargetPos; } if (unit.AgentType == EAgentType.astar && unit.agent != null) { AStarAgent ag = unit.agent as AStarAgent; if (debugDrawPath) { for (int i = 1; i < ag._vecRunningPath.Count; i++) { UnityEngine.Debug.DrawLine(CustomMath.TsVecToVector3(ag._vecRunningPath[i - 1]), CustomMath.TsVecToVector3(ag._vecRunningPath[i]), UnityEngine.Color.green, 1); } } #if UNITY_EDITOR ag._showDebug = debugDrawPath; #endif _pathNodeIdx = ag.TowardPathIdx; _totalPathNodeCount = ag._vecRunningPath.Count; } }
/// <summary> /// /// </summary> /// <param name="forceToApply">basic force</param> /// <param name="basicVelocity">basic Velocity</param> /// <returns></returns> protected TSVector ApplyForce(FP deltaTime, TSVector desiredDirection, TSVector basicVelocity, TSVector pos, List <IAgentBehaviour> agents, bool bUsePreForce, bool bSkipStatic)// { // isTminStaticAgent = false; int count = agents.Count; TSVector boidsVelocity = TSVector.zero; //TSVector forceToApply = TSVector.zero; TSVector forceToApply = TSVector.zero; TSVector avoidObstacle = TSVector.zero; FP mAvoidObstacle = FP.Zero; if (IsBoisTypeActive(EBoidsActiveType.terrainSeperation) && false) { avoidObstacle = Boids.BoidsBehaviourAvoidObstacle(pos, _behaviour.map, basicVelocity); //desiredDirection = (desiredDirection + dir * S_terrainSepFactor); //if(desiredDirection!=TSVector.zero) //{ // desiredDirection = desiredDirection.normalized; //} avoidObstacle = CustomMath.Normalize(avoidObstacle, out mAvoidObstacle); } if (desiredDirection != TSVector.zero) { desiredDirection = CustomMath.Normalize(desiredDirection); forceToApply += Boids.SteerTowards(_behaviour, desiredDirection, basicVelocity); } if (mAvoidObstacle > FP.Zero) { forceToApply += Boids.SteerTowards(_behaviour, avoidObstacle, basicVelocity); } if (PathFindingManager.c_useAvoidUnit) { if (IsBoisTypeActive(EBoidsActiveType.avoidUnit)) { TSVector avoidVector = SteerForUnitAvoidance.GetDesiredSteering(_behaviour); TSVector force = TSVector.ClampMagnitude(avoidVector / deltaTime * _behaviour.baseData.invMass, _behaviour.baseData.maxForce); forceToApply += force; } //else if (IsBoisTypeActive(EBoidsActiveType.collisionAvoidance)) //{ // // bool isTminStaticAgent = false; // forceToApply += CustomMath.TSVec2ToVec(ForceBasedAgent.computeForces(_behaviour, basicVelocity,out isTminStaticAgent)); //} } if (_activeBoids > 0 && !bUsePreForce && (IsBoisTypeActive(EBoidsActiveType.seperation) || IsBoisTypeActive(EBoidsActiveType.cohesion) || IsBoisTypeActive(EBoidsActiveType.alignment))) { // int count =(i%3== _updateStart)? this.neighbours.Count:0;//_group._thiss TSVector totalForce = TSVector.zero; TSVector averageHeading = TSVector.zero; TSVector centerOfMass = TSVector.zero; int neighboursCountSep = 0; int neighboursCountAlig = 0; int neighboursCountCoh = 0; FP radius = _behaviour.colliderRadius * 4; FP sepSqr = radius * radius;// FP nrSqr = _behaviour.baseData.neighbourRadiusSqr * FP.EN2 * 25; for (int j = 0; j < count; j++) { IAgentBehaviour a = agents[j];// _behaviour.neighbours if (IsBoisTypeActive(EBoidsActiveType.seperation)) { Boids.BoidsBehaviourSeparation(_behaviour, a, sepSqr, ref totalForce, ref neighboursCountSep, bSkipStatic); } if (IsBoisTypeActive(EBoidsActiveType.alignment)) { Boids.BoidsBehaviourAlignment(_behaviour, a, nrSqr, ref averageHeading, ref neighboursCountAlig); } if (IsBoisTypeActive(EBoidsActiveType.cohesion)) { Boids.BoidsBehaviourCohesion(_behaviour, a, nrSqr, ref centerOfMass, ref neighboursCountCoh); } if (a.enabled && a.agent == null) //the ally neighbour has a target, //cause this agent change type to atar type targeted to the same target { PathFindingAgentBehaviour agent = _behaviour as PathFindingAgentBehaviour; if (agent.AgentType == EAgentType.flowFiled) { TSVector target = (a as PathFindingAgentBehaviour).targetPos; bool isDefaultTaget = target == a.baseData.defaultTargetPos; if (target != TSVector.MaxValue && target != TSVector.MinValue && !isDefaultTaget) { agent.stopMoving = false; agent._hasNeighbourTargetedDefaultPos = true; target.y = 0; agent.SetNewTargetPos(target, true); } if (!isDefaultTaget) { agent.preVelocity = TSVector.zero; forceToApply = TSVector.zero; // agent.velocity = TSVector.zero; // agent.ChangeAgentType(EAgentType.astar); return(forceToApply); } } } } if (count > 0) { TSVector sep = TSVector.zero; if (totalForce != TSVector.zero) { //totalForce.Multiply(agent.maxForce / neighboursCount) sep = totalForce * (_behaviour.baseData.maxForce) / neighboursCountSep; //sep=Boids.SteerTowards(_behaviour, sep, basicVelocity); // FP lenSqr = sep.sqrMagnitude; if (lenSqr > _behaviour.baseData.maxForceSqr) { FP fval = _behaviour.baseData.maxForce / TSMath.Sqrt(lenSqr); sep = sep * fval; } } TSVector avh = TSVector.zero; if (averageHeading != TSVector.zero) //average heading { averageHeading = averageHeading / (neighboursCountAlig); avh = Boids.SteerTowards(_behaviour, CustomMath.Normalize(averageHeading), basicVelocity); } //average position TSVector coh = TSVector.zero; if (centerOfMass != TSVector.zero)// seek that position { centerOfMass = centerOfMass + _behaviour.position; neighboursCountCoh++; centerOfMass = centerOfMass / neighboursCountCoh; coh = Boids.BoidsBehaviourSeek(_behaviour, basicVelocity, centerOfMass); } _preBoidsForce = sep * S_seperationFactor + avh * S_alignmentFactor + coh * S_cohesionFactor; forceToApply += _preBoidsForce; if (PathFindingManager.DEBUG) { #if UNITY_5_5_OR_NEWER && !MULTI_THREAD if (FP.Abs(forceToApply.x) > GridMap.SCALE * 1000 || FP.Abs(forceToApply.z) > GridMap.SCALE * 1000) { UnityEngine.Debug.LogError("forceToApply error!"); } #endif } } } else if (bUsePreForce) { forceToApply += _preBoidsForce; } if (forceToApply != TSVector.zero) { if (TSMath.Abs(forceToApply.x) > _behaviour.baseData.maxForce || TSMath.Abs(forceToApply.z) > _behaviour.baseData.maxForce) //FP lengthSquared = forceToApply.sqrMagnitude; //if (lengthSquared > _behaviour.baseData.maxForceSqr)//&& _activeBoids!=(byte)EBoidsActiveType.seperation) { forceToApply = forceToApply * FP.EN3; forceToApply = _behaviour.baseData.maxForce * forceToApply.normalized; } return(forceToApply * _behaviour.baseData.invMass);// } return(forceToApply); }