virtual public void Revive() { curedEnemies.Remove(this); targeted = false; health = maxHealth; agent.stoppingDistance = initialStoppingDistance; agent.SetDestination(transform.position); nextPatrolPoint = 0; state = State.DEFAULT; defaultSubState = DefaultSubState.NOT_DEFAULT; attackSubState = AttackSubState.NOT_ATTACKING; searchSubState = SearchSubState.NOT_SEARCHING; isStunned = false; sprite.color = Color.white; canStun = true; audioSource.clip = walkSounds; GetComponent <Collider>().enabled = true; killed = false; enemyAnimations.SetBool("Cured", false); StopAllCoroutines(); }
virtual protected void PerformSearchingState() { switch (searchSubState) { case SearchSubState.NOT_SEARCHING: pointsToSearch.Clear(); agent.SetDestination(playerTransform.position); searchSubState = SearchSubState.CHECK_LAST_POS; break; case SearchSubState.CHECK_LAST_POS: //Exit Case: enemy arrives at last known position of player if (agent.remainingDistance < agent.stoppingDistance) { searchSubState = SearchSubState.PICK_SEARCH_POINTS; } break; case SearchSubState.PICK_SEARCH_POINTS: //pick three new search points around the enemy's location for (int i = 0; i < 3; i++) { pointsToSearch.Add(transform.position + (new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)).normalized * 2.5f)); } searchSubState = SearchSubState.ARRIVED_AT_POINT; break; case SearchSubState.MOVING_TO_POINT: if (agent.remainingDistance < agent.stoppingDistance) { searchSubState = SearchSubState.ARRIVED_AT_POINT; } break; case SearchSubState.ARRIVED_AT_POINT: if (pointsToSearch.Count > 0) { StartCoroutine(SetDestinationAfter(pointsToSearch[0], timeAtPosition)); pointsToSearch.RemoveAt(0); searchSubState = SearchSubState.STOPPED_AT_POINT; } else { StopCoroutine("SetDestinationAfter"); searchSubState = SearchSubState.DONE; } break; case SearchSubState.STOPPED_AT_POINT: if (destinationChanged) { searchSubState = SearchSubState.MOVING_TO_POINT; } break; case SearchSubState.DONE: //Currently Inaccessible break; } }
public void LoadCheckpoint(LevelManager.CheckpointData.EnemyData data) { transform.position = data.worldPosition; transform.rotation = data.worldRotation; transform.parent = data.parent; if (!data.cured) { killed = false; GetComponent <Collider>().enabled = true; enemyAnimations.SetBool("Cured", false); health = data.health; state = State.DEFAULT; attackSubState = AttackSubState.NOT_ATTACKING; searchSubState = SearchSubState.NOT_SEARCHING; defaultSubState = DefaultSubState.NOT_DEFAULT; audioSource.clip = walkSounds; curedEnemies.Remove(this); targeted = false; } else { killed = true; } }
override protected IEnumerator Respawn() { foreach (SpriteRenderer sr in GetComponentsInChildren <SpriteRenderer>()) { sr.enabled = false; } health = maxHealth; transform.position = initialPosition; transform.rotation = initialRotation; agent.stoppingDistance = initialStoppingDistance; agent.SetDestination(transform.position); nextPatrolPoint = 0; state = State.DEFAULT; defaultSubState = DefaultSubState.NOT_DEFAULT; attackSubState = AttackSubState.NOT_ATTACKING; searchSubState = SearchSubState.NOT_SEARCHING; isStunned = false; sprite.color = Color.white; canStun = true; audioSource.clip = walkSounds; yield return(new WaitForSeconds(respawnTime)); foreach (SpriteRenderer sr in GetComponentsInChildren <SpriteRenderer>()) { sr.enabled = true; } GetComponent <Collider>().enabled = true; killed = false; enemyAnimations.SetBool("Cured", false); StopAllCoroutines(); }
virtual protected void PerformAILogic() { //Reset stopping distance if enemy is aware of player if (state != State.DEFAULT) { agent.stoppingDistance = initialStoppingDistance; } //Calculate distance to player float distance = Vector3.Distance(playerTransform.position, transform.position); //reset location flags hasLineOfSight = false; inChaseRadius = false; inAgroRadius = false; inAttackRadius = false; //set location flags if (distance <= chaseLimitRadius) { inChaseRadius = true; hasLineOfSight = RaycastToPlayer(); if (distance <= agroRadius && hasLineOfSight) { inAgroRadius = true; if (distance <= attackRaduis) { inAttackRadius = true; } } } if (PlayerManager.instance.isAlive) { //Implementation of highest level state machine switch (state) { case State.DEFAULT: //Exit case: Player enters agro radius if (inAgroRadius) { state = State.AGRO; defaultSubState = DefaultSubState.NOT_DEFAULT; PerformAgroState(); } else { PerformDefaultState(); } break; case State.AGRO: //Exit case: Player enters attack radius if (inAttackRadius) { state = State.ATTACKING; PerformAttackState(); } //Exit case: Player breaks line of sight or leaves chase radius else if (!hasLineOfSight) { state = State.SEARCHING; PerformSearchingState(); } else { PerformAgroState(); } break; case State.ATTACKING: //Exit Case: enemy finished attacking, return to agro if (attackSubState == AttackSubState.DONE) { state = State.AGRO; attackSubState = AttackSubState.NOT_ATTACKING; PerformAgroState(); } else { PerformAttackState(); } break; case State.SEARCHING: //Exit case: Searching concludes without finding player if (searchSubState == SearchSubState.DONE) { state = State.DEFAULT; searchSubState = SearchSubState.NOT_SEARCHING; PerformDefaultState(); } //Exit case: Enemy finds player else if (hasLineOfSight) { state = State.AGRO; searchSubState = SearchSubState.NOT_SEARCHING; } else { PerformSearchingState(); } break; default: Debug.LogError("Unrecognized State"); break; } } else { searchSubState = SearchSubState.NOT_SEARCHING; attackSubState = AttackSubState.NOT_ATTACKING; state = State.DEFAULT; } }