- Home /
Enemy AI to Discover Waypoints
Dear Coders, I have coded for Waypoints to be Instantiated at random points along my plane :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class WaypointManager : MonoBehaviour {
public Transform wayPointManager;
public GameObject wayPoint;
public List<GameObject> wayPoints = new List<GameObject>();
public float timer;
float x;
float y;
float z;
void Start ()
{
wayPoint = GameObject.FindGameObjectWithTag("WayPoint");
wayPoints.Add (wayPoint);
}
void Update (){
x = Random.Range(-500, 500);
y = Random.Range (1, 5);
z = Random.Range(-500, 500);
timer += Time.deltaTime;
if (timer > 1.0f) {
GenerateARandomWayPoint ();
timer = 0f;
}
if (wayPoints == null || wayPoints.Count == 0)
{
wayPoints.Add (GenerateARandomWayPoint());
}
}
public GameObject GenerateARandomWayPoint(){
bool setRelativeToWorld = true;
GameObject clone = Instantiate (wayPoint,wayPointManager,setRelativeToWorld) as GameObject;
//Instantiate (wayPoint,wayPointManager,setRelativeToWorld) as GameObject;
wayPoint.transform.position = new Vector3 (x,y,z);
return clone;
}
}
I am trying to code for instantiated enemies to recognise these waypoints and navigate along the waypoints randomly. I'm having quite a bit of difficulty with this step and the script for enemy waypoint recognition is as follows :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class RandomEnemyWander : MonoBehaviour {
public float timer;
private NavMeshAgent patrol;
public GameObject [] points;
void Start ()
{
patrol = GetComponent<NavMeshAgent> ();
GameObject [] points = GameObject.FindGameObjectsWithTag("WayPoint");
Transform[] wayPoints = new Transform [points.Length];
for (int i = 0; i < points.Length; i++) {
wayPoints [i] = points [i].transform;
}
}
void Update ()
{
wayPointList ();
}
void wayPointList ()
{
GameObject[] points = GameObject.FindGameObjectsWithTag ("WayPoint");
Transform[] wayPoints = new Transform [points.Length];
for (int i = 0; i < points.Length; i++) {
wayPoints [i] = points [i].transform;
}
}
}
So in essence I want the enemy to recognise when a waypoint has been generated and to add this to a list of waypoints that it can randomly follow.
Could somebody help?
Thanks!
Rather than trying to detect newly added waypoints, why not just keep a list of them somewhere that's accessible by all enemies ? Each time you add a new waypoint, just add it to the list. :)
Thanks for the reply. Would you be able to elaborate? I've been tinkering with the code but nothing seems to be working!
Thanks
In Waypoint$$anonymous$$anager the wayPoints list is public and each time you add a waypoint to the list, it will always have all points available, right ?
The idea is that your Enemies get access to that list ins$$anonymous$$d of having to check for newly created waypoints themselves, by doing GameObject.Find(...), just look up the "wayPoints" list in Waypoint$$anonymous$$anager and get all the waypoints from there.
Since the Waypoint$$anonymous$$anager is a script most likely attached to some GameObject in the Scene, you could ins$$anonymous$$d, in your RandomEnemyWander script use that GameObject to get access to the Waypoint$$anonymous$$anager script.
For example: 1) Add the following to your RandomEnemyWander : public GameObject Waypoint$$anonymous$$anagerObject; //assign this in the Editor
2) Replace
public GameObject [] points; with List points;
3) in the start() method: points = Waypoint$$anonymous$$anagerObject.getComponent().wayPoints;
just make sure not to try and do any changes to "points" in the RandomEnemyWander as it will affect the wayPoints list in the Waypoint$$anonymous$$anager and everything else that's pointing to it.
Alternatively you try to find the Waypoint$$anonymous$$anager script in the scene directly, but that's just another way of accessing the wayPoints list :)
Answer by ohkayem · Dec 21, 2017 at 10:23 PM
Thanks for your help.
So this is what I have so far -
Firstly a cleaner script for the waypoint manager :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEngine.AI;
public class WaypointList : MonoBehaviour {
public GameObject _gameObject;
public List<GameObject> _list = new List<GameObject>();
public float timer;
float x;
float y;
float z;
void Start (){
}
void Update ()
{
List<GameObject> _list = new List<GameObject>();
timer += Time.deltaTime;
if (timer > 1.0f) {
WaypointGenerate();
timer = 0f;
}
x = Random.Range(-500, 500);
y = Random.Range (1, 5);
z = Random.Range(-500, 500);
}
void WaypointGenerate ()
{
GameObject clone = Instantiate (_gameObject) as GameObject;
clone.transform.position = new Vector3 (x,y,z);
_list.Add (_gameObject);
}
}
and a script that allows the enemy to recognise the list :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEngine.AI;
public class RandomEnemyWander : MonoBehaviour {
public float timer;
private NavMeshAgent patrol;
public List<GameObject> points;
public GameObject wayPointManagerObject;
[HideInInspector] WaypointList wplist;
public int index;
GameObject currentPoint;
[HideInInspector] GameObject wpClone;
void Start ()
{
patrol = GetComponent<NavMeshAgent> ();
wplist = wayPointManagerObject.GetComponent<WaypointList> ();
points = wplist._list;
}
void Update (){
timer += Time.deltaTime;
if (timer > 10.0f) {
pickWayPoint ();
timer = 0f;
}
}
public void pickWayPoint (){
index = Random.Range (0, points.Count);
currentPoint = points [index];
patrol.destination = currentPoint.transform.position;
Debug.Log (currentPoint.name);
}
}
These scripts are working beautifully. The enemy object generates a list of waypoints and can randomly pick an index in the list of waypoints. However theres another issue. The enemy only ever moves toward the original waypoint gameobject and none of the clones. So even though it can generate a random index in the waypoint list, it doesn't want to move toward this. Instead, it just moves toward the original waypoint gameobject and stays there.
I've tried tinkering with the scripts - any suggestions?
Thankyou!