// Use this for initialization void Start() { player = GameObject.FindGameObjectWithTag("Player"); buddy = GameObject.FindGameObjectWithTag("buddy"); state = ELEMENTAL_STATE.GUARDING; anim = GetComponent <Animator>(); agent = GetComponent <NavMeshAgent>(); elementalCurrentHealth = GetComponent <EnemyHealth>().enemyHealth; healthManager = GameObject.FindGameObjectWithTag("GUI_Controller"); }
// Update is called once per frame void Update() { /* * Here I calculate the distance to the player, to the players buddy, and to the object that the enemy has been * assigned to guard. */ distanceToBuddy = Vector3.Distance(transform.position, buddy.transform.position); distanceToPlayer = Vector3.Distance(transform.position, player.transform.position); distanceToObjectToGuard = Vector3.Distance(transform.position, objectToGuard.transform.position); elementalCurrentHealth = GetComponent <EnemyHealth>().enemyHealth; //reference to the enemys health if (elementalCurrentHealth <= 0) { state = ELEMENTAL_STATE.DEAD; } /* * Here I cast a raycast to both the player and the players buddy. */ Vector3 castToPlayer = player.transform.position - transform.position; Vector3 castToBuddy = buddy.transform.position - transform.position; Vector3 raycastStartPosition = new Vector3(transform.position.x, transform.position.y + 1, transform.position.z); if (Physics.Raycast(raycastStartPosition, castToPlayer, out hit)) { if (hit.collider.gameObject.tag == "Player") { /* * If the raycast hits the player, that means this enemy can see the player, and so it changes its state * to ATTACK */ if (distanceToPlayer <= 30) { if (state != ELEMENTAL_STATE.DEAD) { state = ELEMENTAL_STATE.ATTACKING; } } } } /* * If the enemys raycast hits the players buddy, then it can see the buddy and changes its state to ATTACK */ if (Physics.Raycast(raycastStartPosition, castToBuddy, out hit)) { if (hit.collider.gameObject.tag == "buddy") { if (distanceToBuddy <= 30) { if (state != ELEMENTAL_STATE.DEAD) { state = ELEMENTAL_STATE.ATTACKING; } } } } /* * I draw the raycasts for debugging purposes in the Editor */ Debug.DrawRay(raycastStartPosition, castToPlayer, Color.blue); Debug.DrawRay(raycastStartPosition, castToBuddy, Color.blue); /* * When GUARDING, the enemy checks its distance to the object it is meant to guard. If it is too far away, it * will move back to the object. If it is near the object, it will continue to guard the object while keeping * an eye out for the player and its buddy */ switch (state) { case ELEMENTAL_STATE.GUARDING: if (distanceToObjectToGuard >= 15) { agent.SetDestination(objectToGuard.transform.position); anim.SetBool("Moving", true); } if (distanceToObjectToGuard <= 15) { anim.SetBool("Moving", false); } break; /* * When ATTACKING, it is possible that the enemy can see both the player and the players buddy at the same * time. So I calculate which enemy is closer using the Mathf.Min function. I then set the enmy to attack * whichever is closer, the player or the buddy as that is the one that is the biggest threat. */ case ELEMENTAL_STATE.ATTACKING: anim.SetBool("Moving", true); float distanceToClosestFoe = Mathf.Min(distanceToBuddy, distanceToPlayer); if (distanceToClosestFoe == distanceToBuddy) { agent.SetDestination(buddy.transform.position); } if (distanceToClosestFoe == distanceToPlayer) { agent.SetDestination(player.transform.position); } if (distanceToClosestFoe >= 20) { state = ELEMENTAL_STATE.GUARDING; } /* * Goes berserk if the player or his buddy is near. The code below makes the enemy choose any attack * animation from a number of possible ones. */ if (distanceToClosestFoe <= 8) { string attackTriggers = string.Format("Attack {0}", Random.Range((int)1, (int)4)); anim.SetTrigger(string.Format("Attack {0}", Random.Range((int)1, (int)4))); } /* * Here the enemy damages the player and the players buddy if they are in range of its attack */ if (distanceToBuddy <= 5) { healthManager.SendMessage("BuddyTakeDamage", damage, SendMessageOptions.DontRequireReceiver); } if (distanceToPlayer <= 5) { healthManager.SendMessage("PlayerTakeDamage", damage, SendMessageOptions.DontRequireReceiver); } //Debug.Log("Distance to closest foe is " + distanceToClosestFoe); break; /* * Enemy is dead if it enters this state */ case ELEMENTAL_STATE.DEAD: collider.enabled = false; anim.SetTrigger("Die"); StartCoroutine("Die"); break; } }