void Update() { //if the state is one then call that function if (aiStates == patrolStates.Flee) { Flee(); } if (aiStates == patrolStates.Waypoint) { Waypoint(); } if (aiStates == patrolStates.Chase) { Chase(); } if (aiStates == patrolStates.Patrol) { Patrol(); } if (aiStates == patrolStates.Shoot) { Shoot(lastSeen); } if (pawn.health <= pawn.retreatHealth) { aiStates = patrolStates.Flee; } }
void Flee() { if (Time.time >= fleeTimer) { // adding time to make sure timer is happening fleeTimer = Time.time + fleeDelay; } else { aiStates = patrolStates.Patrol; } // this is what the vector is from the player to the target Vector3 vectorToTarget = lastSeen.position - transform.position; // now we need to make it negative to move AWAY from the player Vector3 vectorAwayFromTarget = vectorToTarget * -1; // now we need to normalize it to make it so the magnitude is one vectorAwayFromTarget.Normalize(); // now a normalized vector can use multiplication to set the lenght of the vector vectorAwayFromTarget *= pawn.fleeDistance; // now we can use the new vectors to find the space we want to move to, this will give a point away from the player Vector3 fleePosition = vectorAwayFromTarget + transform.position; // this is just a placeholder because i coudln't figure it out //TODO fix the flee script mover.Move(-1); }
protected void Shoot(Transform target) { transform.LookAt(target); shoot.Fire(); if (!Physics.Linecast(transform.position, target.position, PlayerMask)) { aiStates = patrolStates.Chase; } }
protected void Patrol() { // DO nothing this is innate inside of the vision script mover.Move(1); if (patrolTimer <= Time.time) { aiStates = patrolStates.Waypoint; } }
protected void Chase() { //the Enemy will move towards the last seen location of the player mover.Move(1); Movetowards(lastSeen); if (Vector3.Distance(transform.position, lastSeen.position) <= closeEnough) { patrolTimer = Time.time + pawn.patrolDelay; aiStates = patrolStates.Patrol; } }
//---Determine my state and priorities--- public IEnumerator DetermineBehaviour() { //yield return new WaitForEndOfFrame(); yield return(new WaitForSeconds(1)); if (UnityEditor.Selection.activeGameObject == gameObject) { string resString = ""; if (topTier == decisionCategory.Combat) { resString = combatState.ToString(); } else if (topTier == decisionCategory.Patrol) { resString = patState.ToString(); } else if (topTier == decisionCategory.Survival) { resString = survState.ToString(); } Debug.Log(gameObject.name + " called from " + topTier.ToString() + " " + resString); } float threat = CalcThreat(); float bravery = CalcBravery(); float condition = CalcCondition(); //yield return new WaitForEndOfFrame(); yield return(new WaitForSeconds(1)); //determine priorities for (int i = 0; i < priorities.Count; i++) { Priorities pri = priorities[i]; if (pri.key == "Health") { pri.value = 5 - (health / maxHealth) * 5; } if (pri.key == "Cover") { if (!behindCover && haveLOS) { pri.value = 10 - (health / maxHealth) * 10; } else { pri.value = 0; } } if (pri.key == "Ammo") { pri.value = 4 - (ammo / maxAmmo) * 4; } if (pri.key == "Fighting") { pri.value = 3; //pri.value = 5 - ((int)threat / (int)bravery) * 5; //this will need refining } if (pri.key == "Escape") { //pri.value = 4 - ((int)threat / (int)bravery) * 4; //this will need refining } priorities[i] = pri; } SortPriorities(); //Outputs(); //Determine which high level state we're in if (priorities[0].key == "Health" && priorities[0].value > 3 || priorities[0].key == "Cover" && priorities[0].value > 3 || priorities[0].key == "Escape" && priorities[0].value > 3 || priorities[0].key == "Ammo" && priorities[0].value > 3) { topTier = decisionCategory.Survival; } else if (priorities[0].key == "Fighting" && priorities[0].value >= 1) { topTier = decisionCategory.Combat; } else { topTier = decisionCategory.Patrol; } //yield return new WaitForEndOfFrame(); yield return(new WaitForSeconds(1)); //Determine which low level state we're in if (topTier == decisionCategory.Patrol) { anim.SetBool("NonCombat", true); //determine ideal patrol behaviour if (threat > 1 && !haveLOS) { patState = patrolStates.Seek; Seek(); } else { int choice = Random.Range(0, 2); if (choice == 0) { patState = patrolStates.Idle; Idle(); } else { patState = patrolStates.Wander; Wander(); } } if (UnityEditor.Selection.activeGameObject == gameObject) { Debug.Log(gameObject.name + " result is " + topTier.ToString() + " " + patState.ToString()); } } else if (topTier == decisionCategory.Combat) { //determine course of action for combat anim.SetBool("NonCombat", false); if (haveLOS && ammo > 0) { if (UnityEditor.Selection.activeGameObject == gameObject) { Debug.Log(gameObject.name + " should attack"); } combatState = combatStates.Attack; Attack(); } else if (haveLOS && ammo == 0) { combatState = combatStates.Charge; Charge(); } else { combatState = combatStates.Reposition; Reposition(); } if (UnityEditor.Selection.activeGameObject == gameObject) { Debug.Log(gameObject.name + " result is " + topTier.ToString() + " " + combatState.ToString()); } } else if (topTier == decisionCategory.Survival) { anim.SetBool("NonCombat", true); if (priorities[0].key == "Health") { survState = survivalStates.SeekHealth; SeekHealth(); } else if (priorities[0].key == "Cover") { survState = survivalStates.SeekCover; SeekCover(); } else if (priorities[0].key == "Escape") { survState = survivalStates.Run; Run(); } else if (priorities[0].key == "Ammo") { survState = survivalStates.SeekAmmo; SeekAmmo(); } if (UnityEditor.Selection.activeGameObject == gameObject) { Debug.Log(gameObject.name + " result is " + topTier.ToString() + " " + survState.ToString()); } } yield return(new WaitForEndOfFrame()); //yield return new WaitForSeconds(1); //StopCoroutine("DetermineBehaviour"); }
// vision Script //step one: determine with a sphere collider if things are around us void OnTriggerStay(Collider Other) { // these are the necessary locations for vision Vector3 MyPosition = transform.position; Vector3 MyVector = transform.forward; Vector3 TheirPosition = Other.transform.position; Vector3 ThierVector = TheirPosition - MyPosition; //step 2: is the object in front of this enemy //this part just checks for ifsomething is in front of it float mag = Vector3.SqrMagnitude(MyVector) * Vector3.SqrMagnitude(ThierVector); //prevent devide by zero if (mag == 0f) { return; } float dotProd = Vector3.Dot(MyVector, ThierVector); bool isNegative = dotProd < 0f; dotProd = dotProd * dotProd; // square will eliminate negative values but we do still want to keep them if (isNegative) { dotProd *= -1; } float sqrAngle = Mathf.Rad2Deg * Mathf.Acos(dotProd / mag); bool IsInFront = sqrAngle < HalfConeSize; if (Other.gameObject.tag == "Player") { } //step 3: is there anything infront of the object Debug.DrawLine(MyPosition, TheirPosition, IsInFront ? Color.green :Color.red); if (IsInFront) { // make sure that the layermask can pnly hit what we want int mask = 1 << LayerMask.NameToLayer("Env"); PlayerMask = 1 << LayerMask.NameToLayer("player"); if (Physics.Linecast(MyPosition, TheirPosition, mask)) { } if (!Physics.Linecast(MyPosition, TheirPosition, mask)) { if (Other.gameObject.tag == "Player") { //this sets the players last seen location into a variable that the enemy can seek for lastSeen = Other.transform; aiStates = patrolStates.Shoot; } } else { // this is how the tanks move if (sqrAngle <= 90 && isNegative) { mover.Turn(-1); } if (sqrAngle <= 90 && !isNegative) { mover.Turn(1); } //redundency if (sqrAngle > 90 && isNegative) { mover.Turn(-1); } if (sqrAngle > 90 && !isNegative) { mover.Turn(1); } } } }