- Home /
The question is answered, right answer was accepted
Array GameObjects Destinations NavMeshAgent
Hi, please i need help with script. I have script with add gameobject(clone) after mouse click. Separate. And have NavMeshAgent. I need that Agent go to created object and after created next object, agent move to new object and go back to first object. I have loop script patrol, but only with static created objects. Someone help please?
void Start () {
m_Animator = GetComponent<Animator> ();
m_NavAgent = GetComponent<NavMeshAgent> ();
int CountTarget = GameObject.FindGameObjectsWithTag("BuildX").Length;
if (CountTarget == 0) {
return;
} else {
var firstTarget = GameObject.FindWithTag("BuildX").transform.position;
GotoNextPoint();
}
}
void GotoNextPoint() {
m_NavAgent.SetDestination(GameObject.FindWithTag("BuildX").transform.position);
}
// Update is called once per frame
void Update () {
if (!m_NavAgent.pathPending && m_NavAgent.remainingDistance < 0.5f) {
GotoNextPoint ();
} else {
m_Runnging = true;
}
m_Animator.SetBool ("running", m_Runnging);
}
This is what I wrote for such purposes recently, and it works great. Obviously you can handle animating the entity or whatever yourself, but this does the navmesh pathing. Also, supports enabling/disabling.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Nav$$anonymous$$eshPather : $$anonymous$$onoBehaviour {
public Transform[] path;
public UnityEngine.AI.Nav$$anonymous$$eshAgent agent;
private int current;
public bool isOneWay;
// Update is called once per frame
public UnityEngine.Events.UnityEvent OnArrival;
void Update () {
if (agent.enabled && gameObject.activeInHierarchy)
{
if (path.Length > 0)
{
agent.destination = path[current].position;
if (Vector3.Distance(transform.position, path[current].position) < 0.1f)
{
if (current + 1 < path.Length)
{
current++;
}
else if (!isOneWay)
{
current = 0;
}
else
{
agent.destination = transform.position;
enabled = false;
OnArrival.Invoke();
}
}
}
}
}
}
Thanks, but problem is gameobjects are created with instantiate, not added staticaly.
Answer by TheRay · Feb 25, 2018 at 04:03 PM
hanks guys i try write 3 days and solved it. If player create object agent go to him, and stay. If player create new object agent go to him, and start patroling betwen created objects.
private GameObject[] _gameObjects;
private Transform[] _transforms;
private Transform _transform;
private bool m_Runnging = false;
private bool m_Idle = false;
private string gameDataFileName = "/GameData.json";
private int destPoint = 0;
void Start() { m_Animator = GetComponent (); m_NavAgent = GetComponent ();
//m_Idle = true;
//string fileDataPath = Application.dataPath + gameDataFileName;
//string dataAsJson = File.ReadAllText (fileDataPath);
//gameData = JsonUtility.FromJson<GameData> (dataAsJson);
//MovementSpeedChanger();
//_gameObjects = GameObject.FindGameObjectsWithTag ("CommandCenter");
//m_NavAgent.destination = _targetObject.transform.position;
GoToNextSpawnedObject ();
//ChangeMoveSpeed();
}
void GoToNextSpawnedObject() {
_gameObjects = GameObject.FindGameObjectsWithTag ("CommandCenter");
if (_gameObjects.Length == 0) {
return;
}
m_NavAgent.destination = _gameObjects[destPoint].transform.position;
destPoint = (destPoint + 1) % _gameObjects.Length;
}
void Update () {
if (!m_NavAgent.pathPending && m_NavAgent.remainingDistance < 0.5f) {
//GoToBackToWork();
GoToNextSpawnedObject ();
//GotoNextPoint ();
} else {
m_Runnging = true;
}
Answer by melsy · Feb 23, 2018 at 03:11 AM
You are going about this wrong. The best way i have found is creating transforms that are waypoint's. Then put them in a empty game object. Place the waypoints where you want them in the scene. Then run a for method to create an array (or list) of those Transforms and set the destination to the first one.
Then in update have the agent walk to the waypoint and if the distance gets within a threshold , set the agent to move to the next waypoint.
#region Waypoints
public Transform waypointsFolder;
List<Transform> waypoints = new List<Transform>();
// To Index the waypoints;
int indexer = 0;
// How close does the agent need to get to the waypoint before moving to the next
float threshold = 10;
#endregion
public enum MovementType
{
walk,
jog,
run,
sprint
}
[SerializeField]
MovementType movementType;
NavMeshAgent agent;
void Awake()
{
BuildWaypoints();
agent = GetComponent<NavMeshAgent>();
MovementSpeedChanger();
agent.destination = waypoints[indexer].position;
ChangeMoveSpeed();
}
void Update()
{
Waypoints();
}
void FixedUpdate()
{
MovementSpeedChanger();
}
void MovementSpeedChanger()
{
switch (movementType)
{
case MovementType.walk:
agent.speed =1.5f;
return;
case MovementType.jog:
agent.speed =5;
return;
case MovementType.run:
agent.speed = 7;
return;
case MovementType.sprint:
agent.speed = 10;
return;
}
}
// Build the waypoints from the waypoint folder
private void BuildWaypoints()
{
int length = waypointsFolder.childCount;
for (int i = 0; i < length; i++)
{
waypoints.Add(waypointsFolder.GetChild(i));
}
}
// Agent runs to the waypoint and then finds the next and goes there.
void Waypoints()
{
if (Vector3.Distance(agent.transform.position, waypoints[indexer].position) < threshold)
{
indexer++;
if (indexer >= waypoints.Count)
{
indexer = 0;
}
ChangeMoveSpeed();
}
agent.SetDestination(waypoints[indexer].position);
}
// This will just random the move speed at each waypoint Not necessary for the code to work
void ChangeMoveSpeed()
{
int r = Random.Range(0, 4);
switch (r)
{
case 0:
movementType = MovementType.walk;
return;
case 1:
movementType = MovementType.jog;
return;
case 2:
movementType = MovementType.run;
return;
case 3:
movementType = MovementType.sprint;
return;
}
}
}