- Home /
Question by
willaay96 · Aug 02, 2016 at 12:04 PM ·
unity 2daipathfinding
A* Pathfinding Enemy AI, How to search for something else when no path to player available
I've been following a tutorial on how to use A* path finding however, the game I'm making I require the enemy to search for the player, but since I will have objects to stop their path (barricades etc), I need them to first check that there is a path to the player and if not they search for a barricade to destroy and then search for the player again.
here is the current script:
public class EnemyAlienAi : MonoBehaviour {
public Transform target; //enemy target acquired
public float updateRate = 4f; //how many times a second each second we update our path
private Seeker seeker;
private Rigidbody2D rb;
public Path path; //calculated path
public float speed = 300f;
public ForceMode2D fMode;
[HideInInspector]
public bool pathIsEnded = false;
private bool searchingForPlayer = false;
public float nextWayPointDistance = 2; //the max distance from the ai to a waypoint to continue to next waypoint
private int currentWayPoint = 0; //waypoint currently moving towards
void Start () {
seeker = GetComponent<Seeker> ();
rb = GetComponent<Rigidbody2D> ();
transform.position = new Vector3 (transform.position.x, transform.position.y, 0f);
if (target == null) {
//Debug.Log ("No target");
if (!searchingForPlayer) {
searchingForPlayer = true;
StartCoroutine (SearchForPlayer ());
}
return;
//insert a search for target
}
seeker.StartPath (transform.position, target.position, OnPathComplete);
StartCoroutine ("UpdatePath");
}
void Update(){
var dir = target.position - transform.position;
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle + 90, Vector3.forward);
}
IEnumerator SearchForPlayer(){
GameObject searchResult = GameObject.FindGameObjectWithTag ("Player");
if (searchResult == null) {
yield return new WaitForSeconds (0.5f);
StartCoroutine (SearchForPlayer ());
} else {
target = searchResult.transform;
searchingForPlayer = false;
StartCoroutine (UpdatePath ());
return false;
}
}
IEnumerator UpdatePath(){
if (target == null) {
//Debug.Log ("No target");
if (!searchingForPlayer) {
searchingForPlayer = true;
StartCoroutine (SearchForPlayer ());
}
return false;
//insert a search for target
}
seeker.StartPath (transform.position, target.position, OnPathComplete);
yield return new WaitForSeconds (1f / updateRate);
StartCoroutine (UpdatePath());
}
public void OnPathComplete(Path p){
Debug.Log ("We have a path, did it have an error? " + p.error);
if (!p.error) {
path = p;
currentWayPoint = 0;
}
}
void FixedUpdate(){
if (target == null) {
//Debug.Log ("No target");
if (!searchingForPlayer) {
searchingForPlayer = true;
StartCoroutine (SearchForPlayer ());
}
return;
//insert a search for target
}
//TODO: always look at player?
if (path == null) {
return;
}
if (currentWayPoint >= path.vectorPath.Count) {
if (pathIsEnded == true) {
return;
}
Debug.Log ("Path reached.");
pathIsEnded = true;
}
pathIsEnded = false;
Vector3 dir = (path.vectorPath[currentWayPoint] - transform.position).normalized; // direction to next waypoint
dir *= speed * Time.fixedDeltaTime;
rb.AddForce (dir, fMode);//move the ai
float dist = Vector3.Distance(transform.position, path.vectorPath[currentWayPoint]);
if (dist < nextWayPointDistance){
currentWayPoint++;
return;
}
}
`}
Comment
Your answer
Follow this Question
Related Questions
How do I moveTowards all the items in a list one at a time? 1 Answer
Set AI Destination Setter target from Script 2 Answers
A* Pathfinding AIFollow in JavaScript? 0 Answers
[Arongranberg A * Pathfinding Project] How to move units without overlaping of them? 1 Answer
Attacking units surround attacked building properly? (New solution, or fix to Nav Mesh?) 0 Answers