Question by
NxG_Anima · Sep 24, 2017 at 05:35 PM ·
c#scripting problemai2d-platformerpathfinding
A* Pathfinding and keep the enmy at range
Hello everyone! Im following a tutorial on youtube for making my first 2D platformer and decided to make a flying AI with that kind of script. It all works great, and i was able to make a makeshift "player search" coroutine. My problem is that i would like the AI to stay away from the player in a certain range so to have an Ai that bumps into the player and explodes and one that stays at range shooting. I really tried other solutions found in here and else, but i can't insert those because of A* (?) Here is the script. Any help / suggestion on the matter would be great, thanks!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
[RequireComponent (typeof(Rigidbody2D))]
[RequireComponent (typeof(Seeker))]
public class EnemyFlyer : MonoBehaviour {
private Transform target;
public float updateRate = 2f;
public float range = 12f ;
private Seeker seeker;
private Rigidbody2D rb;
public Path path;
private int currentWaypoint = 0;
public float speed = 100f;
public ForceMode2D fmode;
[HideInInspector]
public bool pathIsEnded = false;
public float nextWaypointDistance = 3;
void Start (){
seeker = GetComponent<Seeker> ();
rb = GetComponent<Rigidbody2D> ();
InvokeRepeating ("UpdateTarget", 0f, 0.5f);
StartCoroutine (UpdatePath ());
}
IEnumerator UpdatePath () {
if (target == null) {
yield break;
}
seeker.StartPath (transform.position, target.position , OnPathComplete);
yield return new WaitForSeconds (1f / updateRate);
StartCoroutine (UpdatePath ());
}
public void OnPathComplete (Path p) {
Debug.Log ("Path assigned. Any Errors?" + p.error);
if (!p.error) {
path = p;
currentWaypoint = 0;
}
}
void UpdateTarget() {
GameObject enemy = GameObject.FindGameObjectWithTag ("Player");
float shortestDistance = Mathf.Infinity;
GameObject nearestEnemy = null;
float enemyDistance = Vector3.Distance (transform.position, enemy.transform.position);
if (enemyDistance < shortestDistance) {
shortestDistance = enemyDistance;
nearestEnemy = enemy;
}
if (nearestEnemy != null && shortestDistance <= range) {
target = nearestEnemy.transform;
range = 15f;
seeker.StartPath (transform.position, target.position, OnPathComplete);
} else {
target = null;
}
}
void StartPath(){
seeker.StartPath (transform.position, target.position, OnPathComplete);
}
void FixedUpdate () {
if (target == null) {
range = 12f;
return;
}
//TODO: Always look at player
if (path == null)
return;
if (currentWaypoint >= path.vectorPath.Count) {
if (pathIsEnded)
return;
Debug.Log ("End of Path.");
pathIsEnded = true;
return;
}
pathIsEnded = false;
Vector3 dir = (path.vectorPath [currentWaypoint] - transform.position).normalized;
dir *= speed * Time.fixedDeltaTime;
rb.AddForce (dir, fmode);
float dist = Vector3.Distance (transform.position, path.vectorPath [currentWaypoint]);
if (dist < nextWaypointDistance) {
currentWaypoint++;
return;
}
}
void OnDrawGizmosSelected (){
Gizmos.color = Color.green;
Gizmos.DrawWireSphere (transform.position, range);
}
}
Comment