//combat loop vs enemy warrior //IEnumerator must be returned in cases where WaitForSeconds method is being used IEnumerator InCombat(PlayerWarriorController enemy) { //keep track of first hit so the unit starts attacking as soon as it collides instead of waiting and then begining to attack if (firstHit == false) { GetComponent <AudioSource>().PlayOneShot(swordClashFX, 0.1f); } if (firstHit == true && health > 0) { GetComponent <AudioSource>().PlayOneShot(swordClashFX, 0.1f); yield return(new WaitForSeconds(attackSpeed)); } firstHit = true; //if this warrior dies during combat then call the DIE method if (health <= 0) { AIDie(); } //deduce health from the enemy else if (enemy.health > 0 && animator.GetBool("inRange") == true) { enemy.health = enemy.health - attackDamage; StartCoroutine(InCombat(enemy)); } //else the enemy has been killed thus, reset the warrior else { firstHit = false; resetWarrior(); } }
//detect arrow collisions with the following units, cant check for collisions in respectice class files (warrior, archer) //since those already use an OnCollisionSTAY method void OnCollisionEnter2D(Collision2D col) { //set arrow to isKinematic so that physics engine doesn't knock units over on impact //destory the arrow on impact if (col.transform.tag == "warrior") { Rigidbody2D arrowBody = thisArrow.GetComponent <Rigidbody2D>(); arrowBody.isKinematic = true; PlayerWarriorController warriorObject = col.gameObject.GetComponent <PlayerWarriorController>(); warriorObject.health = warriorObject.health - AIarcherController.attackDamage; Destroy(thisArrow); } if (col.transform.tag == "Archer") { Rigidbody2D arrowBody = thisArrow.GetComponent <Rigidbody2D>(); arrowBody.isKinematic = true; PlayerArcherController archerObject = col.gameObject.GetComponent <PlayerArcherController>(); archerObject.health = archerObject.health - AIarcherController.attackDamage; Destroy(thisArrow); } else { Destroy(thisArrow); } }
//Detects collisions on this warrior's collision box and takes action //according to what it's colliding with void OnCollisionStay2D(Collision2D col) { if (col.transform.tag == "AIwarrior") { colAnimator = col.transform.GetComponent <Animator> (); //get reference to the warrior's animator that is colliding with this warrior Vector2 relativePosition = transform.InverseTransformPoint(col.transform.position); if (relativePosition.x < 0) //check whether the AI warrior this warrior has collided with is infront (to the left) of itself { colAnimator.SetBool("isIdle", true); } } //if this warrior has collided with an enemy warrior then call the combat routine if (col.transform.tag == "warrior" && animator.GetBool("inRange") == false) { PlayerWarriorController warriorObject = col.gameObject.GetComponent <PlayerWarriorController>(); animator.SetBool("inRange", true); animator.SetBool("isIdle", false); StartCoroutine(InCombat(warriorObject)); //get the reference of the enemy warrior and pass it to the combat method } //if this warrior has collided with an enemy castle then call the castle combat routine if (col.transform.tag == "PlayerCastle" && animator.GetBool("inRange") == false) { HealthBar castleObject = col.gameObject.GetComponent <HealthBar>(); animator.SetBool("inRange", true); animator.SetBool("isIdle", false); StartCoroutine(InCombat(castleObject)); //get the reference of the enemy castle healthbar and pass it to the combat method } //if this warrior has collided with an enemy worker call the combat routine if (col.transform.tag == "Worker" && animator.GetBool("inRange") == false) { PlayerWorkerController workerObject = col.gameObject.GetComponent <PlayerWorkerController>(); animator.SetBool("inRange", true); animator.SetBool("isIdle", false); StartCoroutine(InCombat(workerObject)); //get the reference of the enemy warrior and pass it to the combat method } if (col.transform.tag == "Archer" && animator.GetBool("inRange") == false) { PlayerArcherController archerObject = col.gameObject.GetComponent <PlayerArcherController>(); animator.SetBool("inRange", true); animator.SetBool("isIdle", false); StartCoroutine(InCombat(archerObject)); //get the reference of the enemy warrior and pass it to the combat method } }
//findgameobject with an equal tag, if no such object currently exists, look for the next unit in range void GetTarget() { target = GameObject.FindGameObjectWithTag("warrior"); if (target == null) { target = GameObject.FindGameObjectWithTag("Archer"); } if (target == null) { target = GameObject.FindGameObjectWithTag("Worker"); } if (target == null) { target = GameObject.FindGameObjectWithTag("PlayerCastle"); } //check to see if the found enemy unit is in range, otherwise method falls through if (target != null) { distance = Vector3.Distance(transform.position, target.transform.position); targetFound = distance <= maxRange; } //if valid target found then call appropriate Shoot method with target object reference if (targetFound == true) { if (target.transform.tag == "warrior") { PlayerWarriorController warriorObject = target.GetComponent <PlayerWarriorController>(); StartCoroutine(Shoot(warriorObject)); } if (target.transform.tag == "Worker") { PlayerWorkerController workerObject = target.GetComponent <PlayerWorkerController>(); StartCoroutine(Shoot(workerObject)); } if (target.transform.tag == "Archer") { PlayerArcherController archerObject = target.GetComponent <PlayerArcherController>(); StartCoroutine(Shoot(archerObject)); } if (target.transform.tag == "PlayerCastle") { HealthBar castleObject = target.GetComponent <HealthBar>(); StartCoroutine(Shoot(castleObject)); } } }
/*-----------------------------------Overloaded Shoot methods with different parameters------------------------------------------------*/ IEnumerator Shoot(PlayerWarriorController enemyWarrior) { animator.SetBool("inRange", true); //keep track of first hit so the unit starts attacking as soon as it collides instead of waiting and then begining to attack if (firstHit == false) { GetComponent <AudioSource>().PlayOneShot(bowReleaseSFX, 1); } /*if (firstHit == true && health > 0) { * GetComponent<AudioSource>().PlayOneShot (bowReleaseSFX, 1); * yield return new WaitForSeconds (attackSpeed); * }*/ firstHit = true; //if this warrior dies during combat then call the DIE method if (health <= 0) { Die(); } else if (enemyWarrior.health > 0 && animator.GetBool("inRange") == true) { GetComponent <AudioSource>().PlayOneShot(bowReleaseSFX, 1); Instantiate(_arrow, thisArcher.transform.position, Quaternion.identity); yield return(new WaitForSeconds(attackSpeed)); StartCoroutine(Shoot(enemyWarrior)); } //else the enemy has been killed thus, reset the warrior else { firstHit = false; animator.SetBool("inRange", false); } }