public CoverSpot GetCoverTowardsTarget(Soldier soldier, Vector3 targetPosition, float maxAttackDistance, float minAttackDistance, CoverSpot prevCoverSpot) { CoverSpot bestCover = null; Vector3 soldierPosition = soldier.transform.position; CoverSpot[] possibleCoverSpots = unOccupiedCoverSpots.ToArray(); for (int i = 0; i < possibleCoverSpots.Length; i++) { CoverSpot spot = possibleCoverSpots[i]; if (!spot.IsOccupied() && spot.AmICoveredFrom(targetPosition) && Vector3.Distance(spot.transform.position, targetPosition) >= minAttackDistance && !CoverIsPastEnemyLine(soldier, spot)) { if (bestCover == null) { bestCover = spot; } else if (prevCoverSpot != spot && Vector3.Distance(bestCover.transform.position, soldierPosition) > Vector3.Distance(spot.transform.position, soldierPosition) && Vector3.Distance(spot.transform.position, targetPosition) < Vector3.Distance(soldierPosition, targetPosition)) { if (Vector3.Distance(spot.transform.position, soldierPosition) < Vector3.Distance(targetPosition, soldierPosition)) { bestCover = spot; } } } } if (bestCover != null) { bestCover.SetOccupier(soldier.transform); AddToOccupied(bestCover); } return(bestCover); }
public void ExitCover() { if (m_cover != null) { CoverSpot spot = m_cover.GetComponent <CoverSpot>(); if (spot != null) { spot.SetUse(false); spot.SetOwner(null); } m_cover = null; inCover = 0.0f; takingCover = false; /*Uncrouch(); * peek = 0; * crouchPeek = false; * peekCooldown = 500.0f; * crouchPeekCooldown = 500.0f; * peekDur = 0.0f; * crouchPeekDur = 0.0f;*/ //m_waypoint = m_oldpoint; } }
public void ThrowGrenade() { //find cover with enemies Transform tempSpot = null; if (!stacking && order_override <= 0.0f) { //get nearest cover int layerMask = 1 << 9; Collider[] coverSpots = Physics.OverlapSphere(transform.position, 30.0f, layerMask, QueryTriggerInteraction.Collide); float value = 0.0f; foreach (Collider spot in coverSpots) { CoverSpot thisSpot = spot.GetComponent <CoverSpot>(); float newValue = thisSpot.GetEnemyGrenade(); if (newValue > value) { tempSpot = spot.transform; value = newValue; } } if (tempSpot != null) { Debug.DrawLine(tempSpot.transform.position, tempSpot.transform.position + tempSpot.transform.up * value * 0.2f, Color.magenta); } } }
public void ExitCover(CoverSpot spot) { if (spot != null) { spot.SetOccupier(null); AddToUnoccupied(spot); } }
void AddToUnoccupied(CoverSpot spot) { if (occupiedCoverSpots.Contains(spot)) { occupiedCoverSpots.Remove(spot); } if (!unOccupiedCoverSpots.Contains(spot)) { unOccupiedCoverSpots.Add(spot); } }
void stateIdle() { if (curTarget != null && curTarget.GetComponent <Vitals>().getCurHealth() > 0) { if (currentCover != null) { coverManager.ExitCover(currentCover); } currentCover = coverManager.GetCoverTowardsTarget(this, curTarget.transform.position, maxAttackDistance, minAttackDistance, currentCover); if (currentCover != null) { if (Vector3.Distance(myTransform.position, currentCover.transform.position) > 0.2F) { currentPath = CalculatePath(myTransform.position, currentCover.transform.position); anim.SetBool("move", true); state = ai_states.moveToCover; } else { state = ai_states.combat; } } else { if (Vector3.Distance(myTransform.position, curTarget.transform.position) <= maxAttackDistance && Vector3.Distance(myTransform.position, curTarget.transform.position) >= minAttackDistance) { //attack state = ai_states.combat; } } } else { //find new target Soldier bestTarget = GetNewTarget(); if (bestTarget != null) { curTarget = bestTarget; } } }
bool CoverIsPastEnemyLine(Soldier soldier, CoverSpot spot) { bool isPastEnemyLine = false; foreach (Soldier unit in allSoldiers) { if (soldier.myTeam.getTeamNumber() != unit.myTeam.getTeamNumber() && unit.myVitals.getCurHealth() > 0) { if (spot.AmIBehindTargetPosition(soldier.transform.position, unit.transform.position)) { isPastEnemyLine = true; break; } } } return(isPastEnemyLine); }
private void FightUpdate() { StateText.text = "Fighting"; if (!inCover) { coversInRange = Common.FindCover(transform.position, sightRadius, coverMask); if (coversInRange.Length > 0 && choosenCover == null) { CoverSpot checkSpot = Common.EvaluateCover(coversInRange, objInRadius); if (choosenCover != checkSpot) { choosenCover = checkSpot; bool check = (curWaypoint == null); if (!check) { check = curWaypoint != choosenCover.transform.position; } if (check) { Cover coverContainer = choosenCover.CoverContainer; coverContainer.usableCoverSpots.Remove(choosenCover.gameObject); curWaypoint = choosenCover.transform.position; Agent.isStopped = false; Agent.SetDestination(curWaypoint); } } } else if (choosenCover != null) { if (Common.CheckDistanceToPoint(transform.position, choosenCover.transform.position, 0.1f)) { inCover = true; Agent.isStopped = true; } } } }
public CoverSpot EvaluateCover(CoverSpot[] coversInRange, GameObject[] targets) { CoverSpot result = null; float curValue = 0; int curTargetsHit = 0; foreach (CoverSpot cs in coversInRange) { float value = 0; int targetsHit = 0; foreach (GameObject t in targets) { Vector3 dir = (t.transform.position - cs.transform.position).normalized; float toAdd = Vector3.Angle(cs.transform.forward, dir); if (toAdd <= 75) { targetsHit++; value += toAdd; } } if (result == null) { curValue = value; result = cs; curTargetsHit = targetsHit; } else if (value < curValue && value != 0 || targetsHit >= curTargetsHit) { curTargetsHit = targetsHit; curValue = value; result = cs; } } return(result); }
public void TakeCover() { //find cover if (!takingCover) { //m_oldpoint = m_waypoint; //get nearest cover int layerMask = 1 << 9; Collider[] coverSpots = Physics.OverlapSphere(transform.position, 30.0f, layerMask, QueryTriggerInteraction.Collide); float value = 200000.0f; foreach (Collider spot in coverSpots) { CoverSpot thisSpot = spot.GetComponent <CoverSpot>(); if (!thisSpot.InUse()) { UnityEngine.AI.NavMeshPath testPath = new UnityEngine.AI.NavMeshPath(); m_agent.CalculatePath(spot.transform.position, testPath); float tempDist = 0.0f; Vector3 prevCorner = testPath.corners[0]; for (int i = 1; i < testPath.corners.Length; i++) { Vector3 curCorner = testPath.corners[i]; float thisDist = Vector3.Distance(prevCorner, curCorner); tempDist += thisDist; if (Physics.Raycast(prevCorner, (curCorner - prevCorner), thisDist, (1 << 12))) { tempDist += 100.0f; } prevCorner = curCorner; } float newDanger = thisSpot.GetSquadDanger(); float shootable = 0.0f; if (thisSpot.IsLow()) { //shootable = 40.0f; } float closeTarget = 0.0f; if (m_target != null) { //closeTarget = Vector3.Distance(spot.transform.position, m_target.position) * 15.0f; } float newValue = (tempDist * 15.0f) + newDanger - shootable + closeTarget; if (newValue < value) { //Debug.Log(tempDist + " " + newDanger + " " + newValue); m_cover = spot.transform; value = newValue; } } } CoverSpot checkSpot = m_cover.GetComponent <CoverSpot>(); if (checkSpot != null) { checkSpot.SetUse(true); checkSpot.SetOwner(transform); inCover = 3000.0f; takingCover = true; holding = false; } } }
void stateMoveToCover() { if (curTarget != null && currentCover != null && currentCover.AmICoveredFrom(curTarget.transform.position)) { if (currentPath != null) { Soldier alternativeTarget = GetNewTarget(); if (alternativeTarget != null && alternativeTarget != curTarget) { float distanceToCurTarget = Vector3.Distance(myTransform.position, curTarget.transform.position); float distanceToAlternativeTarget = Vector3.Distance(myTransform.position, alternativeTarget.transform.position); float distanceBetweenTargets = Vector3.Distance(curTarget.transform.position, alternativeTarget.transform.position); if (Mathf.Abs(distanceToAlternativeTarget - distanceToCurTarget) > 5 && distanceBetweenTargets > 5) { curTarget = alternativeTarget; coverManager.ExitCover(currentCover); currentCover = coverManager.GetCoverTowardsTarget(this, curTarget.transform.position, maxAttackDistance, minAttackDistance, currentCover); currentPath = CalculatePath(myTransform.position, currentCover.transform.position); return; } } if (currentPath.ReachedEndNode()) { //if we reached the end, we'll start looking for a target anim.SetBool("move", false); currentPath = null; state = ai_states.combat; return; } Vector3 nodePosition = currentPath.GetNextNode(); if (Vector3.Distance(myTransform.position, nodePosition) < 1) { //if we reached the current node, then we'll begin going towards the next node currentPath.currentPathIndex++; } else { //else we'll move towards current node myTransform.LookAt(nodePosition); myTransform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); } } else { //if we don't have a path, we'll look for a target anim.SetBool("move", false); state = ai_states.idle; } } else { anim.SetBool("move", false); state = ai_states.idle; } }
private void FindBestCoverPoint(AI ai) { if (!StoreCoverVarInName.IsValid || !StoreCoverVarInName.IsVariable) { return; } //We don't actually have to have an enemy. We can choose cover points that are simply near ourselves. Vector3 tEnemyPosition = ai.Kinematic.Position; //Assign a current enemy target if (EnemyVariable.IsValid && EnemyVariable.IsVariable) { //using a MoveLookTarget lets us automatically convert between gameObject, Vector3, etc., when getting //a position from AI memory tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, EnemyVariable.VariableName, ai.Motor.CloseEnoughDistance); if (tTarget.IsValid) { tEnemyPosition = tTarget.Position; } } //Cover points should be marked with the "cover" entity for (int i = 0; i <= ai.Senses.Sensors.Count; i++) { if (ai.Senses.Sensors [i].SensorName == CoverDetector.VariableName) { CoverSensor = ai.Senses.Sensors [i] as VisualSensor; break; } } CoverSensor.Sense(CoverEntityName.VariableName, RAINSensor.MatchType.ALL); Vector3 previousCoverAspect = ai.Kinematic.Position;; //Default cover point is our own position float bestCost = float.MaxValue; Vector3 tCoverPosition = ai.Kinematic.Position; //return the closest position out of all found positions //that the player cannot see. for (int i = 0; i < CoverSensor.Matches.Count; i++) { //if your current enemy can see the cover position skip it. //This makes the AI choose a more defensable position. Vector3 ray = (tTarget.Position + adjustment); Vector3 direction = (CoverSensor.Matches[i].Position - (tTarget.Position + adjustment)); RaycastHit hit; if (Physics.Raycast(ray, direction, out hit, 100.0f)) { if (hit.collider.transform.gameObject.GetComponent <CoverSpot> ()) { if (hit.collider.transform.gameObject == CoverSensor.Matches [i].MountPoint.gameObject) { continue; } } } //find all cover matches RAINAspect tCandidateAspect = CoverSensor.Matches[i]; if (tCandidateAspect == null) { continue; } //Cover points are AIObjectives, which are objects that allow AI to "occupy" them CoverSpot tObjective = tCandidateAspect.Entity.Form.GetComponent <CoverSpot>(); //Skip occupied cover points if ((tObjective != null) && (tObjective.isTaken) && (tObjective.occupant == ai.Body)) { previousCoverSpot = tObjective; previousCoverAspect = tCandidateAspect.Position; continue; } if ((tObjective == null) || (tObjective.isTaken && tObjective.occupant != ai.Body)) { continue; } //Our cost function gives 50% more weight to points near the enemy //But then also adds in the AI distance to the point float tCost = 1.5f * Vector3.Distance(tEnemyPosition, tCandidateAspect.Position) + Vector3.Distance(ai.Kinematic.Position, tCandidateAspect.Position); if (tCost < bestCost) { currentCoverPoint = tObjective; tCoverPosition = tCandidateAspect.Position; bestCost = tCost; } } //If we found a cover point, then occupy it if (currentCoverPoint != null) { if (previousCoverSpot != null) { previousCoverSpot.LeaveSpot(ai.Body); } currentCoverPoint.TakeSpot(ai.Body); } else if (previousCoverSpot != null) { tCoverPosition = previousCoverAspect; previousCoverSpot.TakeSpot(ai.Body); } //Set the cover position in AI memory ai.WorkingMemory.SetItem <Vector3>(StoreCoverVarInName.VariableName, tCoverPosition); }
void MainLogic() { if (order_override > 0.0f) { order_override -= 1000.0f * Time.deltaTime; } if (inCombat > 0.0f) { inCombat -= 1000.0f * Time.deltaTime; } if (!takingCover && danger > 50.0f && order_override <= 0.0f) { TakeCover(); } if (danger - lastDanger > 50.0f && order_override <= 0.0f) { RefreshCover(); } if (danger > 0.0f && (danger - lastDanger) <= 0.0f) { danger -= 1000.0f * Time.deltaTime; } lastDanger = danger; if (m_target != null) { AimAngle(m_target, false); inCombat = 3000.0f; } /*else if (m_covertarget != null) * { * AimAngle(m_covertarget); * inCombat = 3000.0f; * }*/ if (stacking) { if (Vector3.Distance(transform.position, m_agent.destination) <= 1.0f) { if (stackCounter < 200.0f) { stackCounter += Time.deltaTime * 1000.0f; } if (stackCounter >= 200.0f) { doneStacking = true; } } } else if (m_waypoint != null) { if (!takingCover) { m_covertarget = null; switch (pos) { //to the left case 1: m_agent.destination = m_waypoint.position - m_waypoint.right * 0.75f; break; //to the right case 2: m_agent.destination = m_waypoint.position + m_waypoint.right * 0.75f; break; //behind case 3: m_agent.destination = m_waypoint.position - m_waypoint.forward * 1.0f; break; //behind left case 4: m_agent.destination = m_waypoint.position - m_waypoint.forward * 2.0f - m_waypoint.right * 1.0f; break; //behind right case 5: m_agent.destination = m_waypoint.position - m_waypoint.forward * 2.0f + m_waypoint.right * 1.0f; break; default: m_agent.destination = m_waypoint.position; break; } } else { if (m_covertarget != null) { m_target = m_covertarget; } if (peek != 0) { if (m_target != null) { AimAngle(m_target, false); } m_agent.destination = m_cover.position + m_cover.right * peek * 2.0f; peekDur -= 1000.0f * Time.deltaTime; if (peekDur <= 0.0f) { m_agent.destination = m_cover.position; peek = 0; //target wasn't seen if (!m_monitor.FinishMonitor()) { ExitCover(); } else { peekCooldown = 1000.0f; } } } else if (crouchPeek) { if (m_target != null) { AimAngle(m_target, false); if (m_monitor.IsMonitoring()) { m_monitor.UpdateMonitor(m_target); } } crouchPeekDur -= 1000.0f * Time.deltaTime; if (crouchPeekDur <= 0.0f) { crouchPeek = false; if (!m_monitor.FinishMonitor()) { ExitCover(); } else { crouchPeekCooldown = 2500.0f; } } } else { m_agent.destination = m_cover.position; if (inCover > 0.0f && Vector3.Distance(transform.position, m_cover.position) < 4.0f) { CoverSpot checkSpot = m_cover.GetComponent <CoverSpot>(); if (checkSpot != null) { if (checkSpot.IsShootable()) { if (m_covertarget != null || checkSpot.IsLow()) { inCover += 1000.0f * Time.deltaTime; CoverShoot(); } //holding = true; } } else { inCover = 0.0f; } inCover -= 1000.0f * Time.deltaTime; if (inCover <= 0.0f) { ExitCover(); if (regroup) { regroup = false; Regroup(); } } } } } } Walk(Vector3.Distance(transform.position, prevPos) * 50.0f); prevPos = transform.position; if (!hasOrder && m_target == null) { CornerCheck(); } if (holding && !takingCover && !stacking) { m_agent.destination = transform.position; } hasOrder = false; }
void CoverShoot() { if (m_covertarget != null) { m_target = m_covertarget; } bool isLeftCorner = false; bool isRightCorner = false; bool isLow = false; CoverSpot checkSpot = m_cover.GetComponent <CoverSpot>(); if (checkSpot != null) { isLeftCorner = checkSpot.IsLeftCorner(); isRightCorner = checkSpot.IsRightCorner(); isLow = checkSpot.IsLow(); if (isLow) { if (crouchPeekCooldown > 0.0f) { crouchPeekCooldown -= 1000.0f * Time.deltaTime; } if (!m_gun[gunOut].Reloading() && !crouchPeek && crouchPeekCooldown <= 0.0f) { //uncrouch Uncrouch(); crouchPeek = true; crouchPeekDur = 300.0f; m_monitor.Monitor(m_target); } if (!crouchPeek) { Crouch(); } } else { AimAngle(m_target, false); if (peekCooldown > 0.0f) { peekCooldown -= 1000.0f * Time.deltaTime; } if (!m_gun[gunOut].Reloading() && peek == 0 && peekCooldown <= 0.0f) { Debug.Log("peeking"); m_monitor.Monitor(m_covertarget); peekDur = 400.0f; if (isLeftCorner) { peek = -1; } else { peek = 1; } } } } }
public void EnterDoor(Transform door, int side, int state) { Debug.Log("attempting to enter door"); if (isLeader) { m_doorstate = state; m_doorside = side; if (takingCover) { takingCover = false; inCover = 0.0f; CoverSpot checkSpot = m_cover.GetComponent <CoverSpot>(); if (checkSpot != null) { checkSpot.SetUse(false); checkSpot.SetOwner(null); holding = false; } } stacking = true; //m_oldpoint = m_waypoint; //m_waypoint = door; m_agent.destination = door.position + door.forward * side; m_agent.destination += door.right * 2.5f; m_door = door; int stackLeft = 0; int stackRight = 1; int neg = -1; foreach (SquadMember squad in m_squad) { if (squad != null) { int thisStack = 0; if (neg == -1) { stackLeft++; thisStack = stackLeft; } else { stackRight++; thisStack = stackRight; } squad.stacking = true; if (squad.takingCover) { squad.takingCover = false; squad.inCover = 0.0f; CoverSpot checkSpot = squad.m_cover.GetComponent <CoverSpot>(); if (checkSpot != null) { checkSpot.SetUse(false); checkSpot.SetOwner(null); squad.holding = false; } squad.m_door = door; //squad.m_waypoint = squad.m_oldpoint; } squad.m_agent.destination = door.position + door.forward * side; squad.m_agent.destination += door.right * (2.5f + (1.0f * thisStack)) * neg; neg *= -1; } } } }