void UpdateAlert() { UpdateSuspicious(); //get the player position Vector3 playerPos = GameObject.Find("Player").GetComponent <Transform>().position; //setup distance for check float distance = Vector3.Distance(playerPos, transform.position); //attack if close if (distance < attackRadius) { RotateTowards(playerPos); gameObject.GetComponent <NavMeshAgent>().isStopped = true; PlayAttackAnimation(); } else { gameObject.GetComponent <NavMeshAgent>().isStopped = false; } //if outside alert radius become suspicious if (distance > maxAlertRadius) //took out = from >= { //change the state to suspicious currentState = (trooperState)1; } }
void UpdateRiverSpawn() { //play swim animation //play jump animation currentState = (trooperState)0; }
// Update is called once per frame void Update() { //switch statement, triggers functions based on which state ai is in switch ((int)currentState) { case 0: //idle UpdateIdle(); break; case 1: //suspicious UpdateSuspicious(); break; case 2: //alert UpdateAlert(); break; case 3: //downed UpdateDowned(); break; case 4: //dead UpdateDead(); break; case 5: //unique spawn (river) UpdateRiverSpawn(); break; case 6: //unique spawn (door) UpdateDoorSpawn(); break; } EnemyTookDamage(); //if the remaining health = downedhealth, state is now downed if (currentHealth <= downedHealth) { currentState = (trooperState)3; //the trooper cannot take damage from normal attacks //hitCollision.gameObject.SetActive(false); hitCollision.enabled = false; //the trooper can now be executed //downedCollision.gameObject.SetActive(true); downedCollision.enabled = true; } if (xIsDeadX) { currentState = (trooperState)4; } }
void UpdateDowned() { //downed animation //PlayDownedAnimation(); xIsDownedX = true; //set destination to itself so it doesnt move //enemyAI.SetDestination(transform.position); gameObject.GetComponent <NavMeshAgent>().isStopped = true; transform.rotation = Quaternion.AngleAxis(90, Vector3.back); //settup timer if (downedCounter >= downedTimeUntilAlive) { //restore the health set in revive health currentHealth = reviveHealthGain; //play getup animation PlayGetUpFromDownedAnimation(); //the trooper can now take damage from normal attacks //hitCollision.gameObject.SetActive(true); //hitCollision.enabled = true; //the trooper cannot be executed //downedCollision.gameObject.SetActive(false); downedCollision.enabled = false; //reset dead counter downedCounter = 0; transform.rotation = Quaternion.AngleAxis(90, Vector3.back); gameObject.GetComponent <NavMeshAgent>().isStopped = false; xIsDownedX = false; //respawn invulerability timer starts justRevived = true; //set to idle currentState = (trooperState)0; } //add to the counter downedCounter += 1 * Time.deltaTime; }
////-------------------Audio Sources //public float idleSoundTimer = 10; //private float idleSoundIterator = 0; ////blade itself swing (shwoooosh) //public AudioSource heavyAttackSound; ////grunts made by trooper when attacking //public AudioSource[] trooperAttackGrunt; ////ouch i got hit by a human //public AudioSource trooperRecievedDamage; ////scream as they get downed //public AudioSource trooperJustDowned; ////scream as they die //public AudioSource trooperNormalDeath; ////long scream that goes away from mic if they fall off edge //public AudioSource trooperPitDeath; ////huh? as they see player (lines 620-623) //public AudioSource trooperJustSuspicious; ////grrr as they chase the player //public AudioSource trooperJustAlert; //// angry confuzzled noise when they lose the player //public AudioSource trooperJustLostPlayer; ////multiple grunts by trooper when they are in idle (lines 376-399) //public AudioSource[] trooperIdleGrunts; // Start is called before the first frame update void Start() { hitCollision = GetComponent <BoxCollider>(); downedCollision = GetComponent <CapsuleCollider>(); //ensure the downed collison is false //downedCollision.gameObject.SetActive(false); downedCollision.enabled = false; trooperAnimation = meleeWeapon.GetComponent <Animator>(); //trooperAnimation = GetComponent<Animator>(); //ensure own rigidbody is correct enemyRigidbody = GetComponent <Rigidbody>(); //false makes it slide like ice but cant go through stuff //true removes knockback //enemyRigidbody.isKinematic = false; //on startup enemy set to idle by default if (wasSpawnedInDoor) { currentState = (trooperState)6; } else if (wasSpawnedInRiver) { currentState = (trooperState)5; } else { currentState = (trooperState)0; } //add the alert and suspicious radius combinedAlertRadius = maxSuspiciousRadius + maxAlertRadius; //store start position idleCentrePosition = this.transform.position; lastKnownPlayerPosition = this.transform.position; player = GameObject.FindGameObjectWithTag("Player").GetComponent <PlayerController>(); }
// Start is called before the first frame update void Start() { hitCollision = GetComponent <BoxCollider>(); downedCollision = GetComponent <CapsuleCollider>(); //ensure the downed collison is false //downedCollision.gameObject.SetActive(false); downedCollision.enabled = false; trooperAnimation = meleeWeapon.GetComponent <Animator>(); //trooperAnimation = GetComponent<Animator>(); //ensure own rigidbody is correct enemyRigidbody = GetComponent <Rigidbody>(); //on startup enemy set to idle by default if (wasSpawnedInDoor) { currentState = (trooperState)6; } else if (wasSpawnedInRiver) { currentState = (trooperState)5; } else { currentState = (trooperState)0; } //add the alert and suspicious radius combinedAlertRadius = maxSuspiciousRadius + maxAlertRadius; //store start position idleCentrePosition = this.transform.position; lastKnownPlayerPosition = this.transform.position; }
void UpdateDoorSpawn() { //play jump through door animation currentState = (trooperState)0; }
void UpdateSuspicious() { //if the ai state is the suspicious state if (currentState == (trooperState)1) { //change ai speed enemyAI.speed = suspiciousWalkSpeed; } //get the player position Vector3 playerPos = GameObject.Find("Player").GetComponent <Transform>().position; //setup distance for checking float distance = Vector3.Distance(playerPos, transform.position); //get cross product of Vector3 direction = (playerPos - transform.position).normalized; //do a raycast to see if the player is within sight Ray ray = new Ray(transform.position, direction); RaycastHit hit = new RaycastHit(); int mask = 1 << LayerMask.NameToLayer("Player"); //if in sight, store playerPos as lastKnownPlayerPosition and go there if (Physics.Raycast(ray, out hit, 9999, mask)) { Debug.DrawRay(transform.position, direction * hit.distance, Color.yellow); if (Physics.Raycast(ray, out hit, distance, ~mask)) { Debug.DrawRay(transform.position, direction * hit.distance, Color.blue); //reset idle returning and justsetdirection idleReturning = false; //justSetDirection = false; //do idle movement UpdateIdle(); } else { //update last known player position lastKnownPlayerPosition = playerPos; //update idle centre position idleCentrePosition = lastKnownPlayerPosition; //travel to the player enemyAI.SetDestination(lastKnownPlayerPosition); } } //if outside the combined radius if (distance >= combinedAlertRadius) { //reset idle returning and justsetdirection idleReturning = false; //justSetDirection = false; //change the state to idle currentState = (trooperState)0; } //if inside the alert radius if (distance <= maxAlertRadius) { //change the state to alert currentState = (trooperState)2; } }
//in this state the ai walks around randomly in a set area void UpdateIdle() { //if the ai state is the idle state if (currentState == (trooperState)0) { //setup the navmesh agent speed enemyAI.speed = idleWalkSpeed; } //choose random direction, 1 = left, 2 = right, 3 = forward, 4 = backward if (!justSetDirection) { //store the previous direction int previousDirection = idleTravelDirection; //if it can walk left/right and NOT up/down if (idleCanWalkLeftRight && !idleCanWalkUpDown) { //the range can only be between 1 and 2 idleTravelDirection = Random.Range(1, 2); } //if it can NOT walk left/right and up/down if (!idleCanWalkLeftRight && idleCanWalkUpDown) { //the range can only be between 3 and 4 idleTravelDirection = Random.Range(3, 4); } //if it can move in all 4, it can be between 1 - 4 if (idleCanWalkLeftRight && idleCanWalkUpDown) { //the range can only be between 1 and 4 idleTravelDirection = Random.Range(1, 4); } //if it cannot travel in any direction for some reason... if (!idleCanWalkLeftRight && !idleCanWalkUpDown) { //the range can only be between 1 and 2 idleTravelDirection = 0; } //timer gets set to random number idleTimer = Random.Range(minIdleTimerRange, maxIdleTimerRange); //idle counter gets reset idleCounter = 0; //we just set the direction so you are now true justSetDirection = true; } //if the direction has been set and the trooper is not returning if (justSetDirection) { //move enemy based on random number assigned to idleTravelDirection if (idleTravelDirection == 1) //left -- opposite is 2 { Vector3 newPosition = new Vector3(transform.position.x + maxIdleTravelDistanceRadius, 0, transform.position.z); enemyAI.SetDestination(newPosition); } if (idleTravelDirection == 2) //right -- opposite is 1 { Vector3 newPosition = new Vector3(transform.position.x - maxIdleTravelDistanceRadius, 0, transform.position.z); enemyAI.SetDestination(newPosition); } if (idleTravelDirection == 3) //forward -- opsosite is 4 { Vector3 newPosition = new Vector3(transform.position.x, 0, transform.position.z + maxIdleTravelDistanceRadius); enemyAI.SetDestination(newPosition); } if (idleTravelDirection == 4) //backward -- oposite is 3 { Vector3 newPosition = new Vector3(transform.position.x, 0, transform.position.z - maxIdleTravelDistanceRadius); enemyAI.SetDestination(newPosition); } if (idleTravelDirection == 0) //go to idle position.... used if idlereturning or no random direction set... { //go to idle position enemyAI.SetDestination(idleCentrePosition); } //add to the counter idleCounter += 1 * Time.deltaTime; } //if idle counter is greater or equal to idletimer and we are not idle returning if (idleCounter >= idleTimer) { //setup next loop justSetDirection = false; //idleReturning = false; } //setup to check if //Vector3 positionPlusIdleTravelDistance = idleCentrePosition; //positionPlusIdleTravelDistance.x = positionPlusIdleTravelDistance.x + maxIdleTravelDistanceRadius; //positionPlusIdleTravelDistance.z = positionPlusIdleTravelDistance.z + maxIdleTravelDistanceRadius; float inRadiusIdlePositive = Vector3.Distance(transform.position, idleCentrePosition); //float inRadiusIdleNegative = Vector3.Distance(transform.position, positionPlusIdleTravelDistance); //if the agent is outside the maxIdleDistance, it should return --------- kinda janky if (inRadiusIdlePositive > maxIdleTravelDistanceRadius /*|| inRadiusIdlePositive < -maxIdleTravelDistanceRadius*/) { idleReturning = true; //set the random number to the one based on opposite direction //if (idleTravelDirection == 1 && !setOppositeTravelDirection) //{ // idleTravelDirection = 2; // setOppositeTravelDirection = true; //} //if (idleTravelDirection == 2 && !setOppositeTravelDirection) //{ // idleTravelDirection = 1; // setOppositeTravelDirection = true; //} //if (idleTravelDirection == 3 && !setOppositeTravelDirection) //{ // idleTravelDirection = 4; // setOppositeTravelDirection = true; //} //if (idleTravelDirection == 4 && !setOppositeTravelDirection) //{ // idleTravelDirection = 3; // setOppositeTravelDirection = true; //} //enemyAI.SetDestination(idleCentrePosition); } else { idleReturning = false; //set to false for future usage in checking travel distance //setOppositeTravelDirection = false; } //if the ai is returning (outside radius) --------- kinda janky? if (idleReturning) { //go to centre of radius -- idle travel direction is set to 0 idleTravelDirection = 0; } //get the player position to check if it is in range Vector3 playerPos = GameObject.Find("Player").GetComponent <Transform>().position; float distance = Vector3.Distance(playerPos, transform.position); //if inside the radius if (distance <= combinedAlertRadius) { //change the state to suspicious currentState = (trooperState)1; } }
// Update is called once per frame void Update() { Physics.IgnoreLayerCollision(0, 12, true); //speed code -------------------------------------------------------------------------------------------------------------- //if you just saw the player but do not currently see them, start timer if (justSawPlayer && !canSeePlayer) { seePlayerIterator += 1 * Time.deltaTime; if (seePlayerIterator >= seePlayerTimer) { justSawPlayer = false; } } else { //reset the timer seePlayerIterator = 0; } //if the player cannot see you or has not seen you if (!justSawPlayer && !canSeePlayer) { enemyAI.speed = idleWalkSpeed; } //if the trooper saw the player AND it is ALERT if (currentState == (trooperState)2 && justSawPlayer) { enemyAI.speed = alertWalkSpeed; } //if the trooper just saw the player if (justSawPlayer && currentState != (trooperState)2) { enemyAI.speed = suspiciousWalkSpeed; } //switch statement, triggers functions based on which state ai is in switch ((int)currentState) { case 0: //idle UpdateIdle(); break; case 1: //suspicious UpdateSuspicious(); break; case 2: //alert UpdateAlert(); break; case 3: //downed UpdateDowned(); break; case 4: //dead UpdateDead(); break; case 5: //unique spawn (river) UpdateRiverSpawn(); break; case 6: //unique spawn (door) UpdateDoorSpawn(); break; } EnemyTookDamage(); //if the remaining health = downedhealth, state is now downed if (currentHealth <= downedHealth) { currentState = (trooperState)3; //the trooper cannot take damage from normal attacks //hitCollision.gameObject.SetActive(false); hitCollision.enabled = false; //the trooper can now be executed //downedCollision.gameObject.SetActive(true); downedCollision.enabled = true; } //peform the revive timer if it just revived if (justRevived) { //update the iteration respawnIteration += 1 * Time.deltaTime; //once the iteration is greater than or equal to the respawn time if (respawnIteration >= respawnInvincibleTime) { //you are no lo9nger just revived justRevived = false; //you can now be hit hitCollision.enabled = true; //reset the iteration respawnIteration = 0; } } if (xIsDeadX) { currentState = (trooperState)4; } }
// Update is called once per frame void Update() { Physics.IgnoreLayerCollision(0, 12, true); //switch statement, triggers functions based on which state ai is in switch ((int)currentState) { case 0: //idle UpdateIdle(); break; case 1: //suspicious UpdateSuspicious(); break; case 2: //alert UpdateAlert(); break; case 3: //downed UpdateDowned(); break; case 4: //dead UpdateDead(); break; case 5: //unique spawn (river) UpdateRiverSpawn(); break; case 6: //unique spawn (door) UpdateDoorSpawn(); break; } EnemyTookDamage(); //if the remaining health = downedhealth, state is now downed if (currentHealth <= downedHealth) { currentState = (trooperState)3; //the trooper cannot take damage from normal attacks //hitCollision.gameObject.SetActive(false); hitCollision.enabled = false; //the trooper can now be executed //downedCollision.gameObject.SetActive(true); downedCollision.enabled = true; } //peform the revive timer if it just revived if (justRevived) { //update the iteration respawnIteration += 1 * Time.deltaTime; //once the iteration is greater than or equal to the respawn time if (respawnIteration >= respawnInvincibleTime) { //you are no lo9nger just revived justRevived = false; //you can now be hit hitCollision.enabled = true; //reset the iteration respawnIteration = 0; } } if (xIsDeadX) { currentState = (trooperState)4; } }