Change Enemy Direction
When the enemy is hit, I need it to target the closest enemy to kill that instead. The code works, but only if the enemy I'm hitting isn't tagged as 'enemy', otherwise it's just looking for itself. I'm not sure how to change the code so that i don't have to use tags or so it doesn't count the tag on itself. using UnityEngine; using System.Collections;
public class EnemyFollow : MonoBehaviour {
public GameObject player;
private NavMeshAgent enemy;
public bool isHit;
void Start ()
{
enemy = GetComponent<NavMeshAgent>();
}
void Update ()
{
if (!isHit)
{
enemy.SetDestination (player.transform.position);
}
else
{
GameObject closest = FindClosestEnemy ();
enemy.SetDestination (closest.transform.position);
}
}
void OnTriggerEnter (Collider col)
{
if (col.gameObject.tag == "Bullet")
{
isHit = true;
}
}
GameObject FindClosestEnemy()
{
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("enemy");
GameObject closest = null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos) {
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance)
{
closest = go;
distance = curDistance;
}
}
return closest;
}
}
Answer by Fredex8 · Mar 20, 2016 at 02:42 AM
There are lots of ways you could accomplish what you are trying to do, problem is I am not especially clear what you are trying to do because the number of times you've used the word 'enemy' has sort of confused me.
It sounds like you have lots of enemies on screen and when the player shoots one it then is meant to attack the nearest enemy to it instead of the player. So some kind of confusion bullets that turn them into friendlies that will fight for you? If that is the case then you could just change the tag of the enemy before running the find script.
void OnTriggerEnter (Collider col)
{
if (col.gameObject.tag == "Bullet")
{
gameObject.tag = "Friendly";
isHit = true;
}
}
Or if you need it to remain tagged as "enemy" just put in a condition to prevent it from looking for itself:
foreach (GameObject go in gos) {
if(go != gameObject)
{
Vector3 diff = go.transform.position - position;
... etc
Alternatively if you are talking about a system where one enemy shoots another and it becomes the target then you might just want to instantiate those bullets with a reference to the enemy that fired them and then set that as the target on collision and remove the closest enemy script entirely.
Another problem you are going to have however is that currently isHit
is never set back to false and FindClosestEnemy ()
is being called in update which means you are running FindGameObjectsWithTag
on every single frame after an enemy is hit and running a for loop on that array. If you've got a lot of enemies and they are all doing this you are going to slow things down significantly.
You should either change it so isHit is reset:
else
{
isHit = false;
GameObject closest = FindClosestEnemy ();
enemy.SetDestination (closest.transform.position);
}
...or remove the FindGameObjectsWithTag
from the FindClosestEnemy
script and instead store and update a list of enemies on a single gameObject in the scene which each enemy can then get when it needs it. If you used this method and used a list instead of an array then you could copy that list into a hit enemy and use enemyList.Remove(gameObject);
to take itself out of the list before trying to find closest, assuming it still needs to be tagged as "enemy".
All depends on what your intended behaviour for these enemies is.
Your answer
Follow this Question
Related Questions
how to search for a random point until the condition is true? 0 Answers
Need support on my basic navmesh ai script to follow the player at a certain distance 1 Answer
Navmesh Agent for direction but not movement? 0 Answers
AI Raycasting Patrol and Chase,AI enemy raycast help 0 Answers
Farthest Reachable Destination 0 Answers