protected GameObject LookForLatchedEnemies() { GameObject chosenEnemy = null; float shortestDistance = Mathf.Infinity; GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag); foreach (GameObject ap in attackPoints) { AttackPoint attackPoint = ap.GetComponent <AttackPoint>(); if (attackPoint != null && !attackPoint.IsVacant()) { float distanceToAP = Vector2.Distance(transform.position, ap.transform.position); if (distanceToAP <= range && distanceToAP < shortestDistance) { shortestDistance = distanceToAP; chosenEnemy = attackPoint.GetOccupant().gameObject; } } } return(chosenEnemy); }
/// <summary> Called with Invoke(). </summary> private void UpdateTarget() { // if it already has a target, see if it's dead or too far away, or if there's another one without an attacker if (target != null) { Enemy targetEnemy = target.GetComponent <Enemy>(); float distanceToTarget = Vector2.Distance(transform.position, target.transform.position); if (distanceToTarget > spotRange) { //Debug.Log("LOST TARGET"); DismissTarget(); return; } // todo: if this target has another attacker, look for nearby enemies without an attacker if (targetEnemy != null && targetEnemy.HasAnotherMeleeAttacker(transform)) { // this target has another attacker; look for other targets without an attacker GameObject[] enemies2 = GameObject.FindGameObjectsWithTag(Constants.EnemyTag); float shortestDistance2 = Mathf.Infinity; GameObject nearestEnemy2 = null; foreach (GameObject enemy in enemies2) { // if the enemy is beyond this unit's spot range, ignore target float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceToEnemy <= spotRange) { // if the enemy has another attacker, ignore it Enemy enemyEnemy = enemy.GetComponent <Enemy>(); if (enemyEnemy != null) { if (!enemyEnemy.HasAnotherMeleeAttacker(transform)) { float distanceFromUnitToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceFromUnitToEnemy < shortestDistance2) { shortestDistance2 = distanceFromUnitToEnemy; nearestEnemy2 = enemy; } } } } } if (nearestEnemy2 != null) { AcquireTarget(nearestEnemy2.transform); } } return; } // if there's no current target, first look for living enemies latched to attack points within range float shortestDistance = Mathf.Infinity; GameObject chosenEnemy = null; GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag); foreach (GameObject ap in attackPoints) { AttackPoint attackPoint = ap.GetComponent <AttackPoint>(); if (attackPoint != null && !attackPoint.IsVacant()) { float distanceToAP = Vector2.Distance(transform.position, ap.transform.position); if (distanceToAP <= spotRange && distanceToAP < shortestDistance) { shortestDistance = distanceToAP; chosenEnemy = attackPoint.GetOccupant().gameObject; } } } // otherwise, find the nearest enemy if (chosenEnemy == null || (chosenEnemy.GetComponent <Enemy>() != null)) { GameObject[] enemies = GameObject.FindGameObjectsWithTag(Constants.EnemyTag); /*float */ shortestDistance = Mathf.Infinity; //GameObject nearestEnemy = null; foreach (GameObject enemy in enemies) { // if this enemy is not dead if (enemy.GetComponent <Enemy>() != null) { // if the enemy is beyond this unit's spot range, ignore target float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position); if (distanceToEnemy <= spotRange && distanceToEnemy < shortestDistance) { shortestDistance = distanceToEnemy; chosenEnemy = enemy; } } } } if (chosenEnemy != null) { //Debug.Log("FOUND TARGET"); AcquireTarget(chosenEnemy.transform); } else { DismissTarget(); } }
private void Update() { if (!started) { return; } if (coughing) { CoughEffect(); } // update the hit countdown and the replication countdown each frame if (hitCountdown > 0f) { hitCountdown -= Time.deltaTime; } if (replicationCoundtown > 0f && !IsBeingAttacked() && !coughing) { replicationCoundtown -= Time.deltaTime; } if (replicationCoundtown <= 0f && !IsBeingAttacked() && !coughing) { Replicate(); } // if there's a melee unit attacking, // start attacking it (face it, move towards it, and if in range, hit) if (meleeAttackers.Count > 0) { //Debug.Log("attacking melee attacker"); // if it's latched, stop the latched animation if (latched) { attackPoint.SetOccupantActive(false); anim.SetBool("isAttackedWhileLatched", true); anim.SetBool("isMoving", true); anim.SetBool("isAtAP", false); if (!attackedWhileLatched) { attackedWhileLatched = true; } //Debug.Log("stopping latched animation"); //if (anim != null) //{ //anim.SetBool("isLatched", false); //anim.SetTrigger("isAttackedWhileLatched"); //} } AttackMeleeAttacker(); } else // if there's no melee attacker, continue towards the next tile { if (nextTile != null) { //Debug.Log("nextTile != null"); // if already latched, don't move if (latched) { anim.SetBool("isAttackedWhileLatched", false); // unless it's too far away from the attack point; in that case, move towards it if (attackPoint != null && Vector2.Distance(transform.position, attackPoint.transform.position) > 0.15f) { //Debug.Log("move closer to attack point"); attackPoint.SetOccupantActive(false); moveable.MoveDirectlyTowardsPosition(attackPoint.transform.position); anim.SetBool("isAtAP", false); } else { //Debug.Log("starting latched animation"); if (anim != null) { anim.SetBool("isStunned", Shop.instance.IsCoughing()); } if (attackedWhileLatched) { attackedWhileLatched = false; attackPoint.SetOccupantActive(!attackedWhileLatched); } anim.SetBool("isAtAP", true); anim.SetBool("isMoving", false); } } else { //Debug.Log("MoveDirectlyTowardsPosition"); moveable.MoveDirectlyTowardsPosition(nextTile.transform.position); if (Vector2.Distance(transform.position, nextTile.transform.position) <= 0.3f) { // it's reached the tile; go to the next tile, unless the current tile is an attack point AttackPoint ap = nextTile.GetComponent <AttackPoint>(); if (ap != null) { if (ap.IsVacant()) { //Debug.Log("ap != null && ap.IsVacant"); // if it's an attack point and it's still vacant, occupy it ap.SetOccupant(this); attackPoint = ap; latched = true; //anim.SetTrigger("isLatched"); anim.SetBool("isLatched", true); anim.SetBool("isMoving", false); } else // if nextTile is an AP that is occupied, clear visited list and get next tile { //Debug.Log("NEXTTILE IS OCCUPIED AP!!!!!!!! clearing visitedTiles and getting next tile!"); visitedTiles.Clear(); GetNextTile(); } } else // otherwise, continue on the path { VisitTile(nextTile); GetNextTile(); } } } } else { //Debug.Log("nextTile == null; calling GetNextTile()"); GetNextTile(); } } }