Search Unity

How to make a NavMeshAgent follow a custom path?

Discussion in 'Navigation' started by FeastSC2, Nov 13, 2019.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Is there a way to make an agent move along a path that's not linear? I have a list of points that draw a cicular movement and I'd like the agent to go along that path.

    How can I create a NavMeshPath with custom points?
     
  2. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    Do you specifically need to create a custom path, or is it enough to get the agent move on a route that passes through those points? If that latter option is ok, you could probably think about using some basic patrol route style approach? Just make the agent travel from point to another; when it's close enough to the first point, set the next waypoint. And repeat until you have no waypoints left in your list. When you have many points it will appear as if it's not linear.
     
  3. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    355
    https://docs.unity3d.com/540/Documentation/ScriptReference/NavMeshAgent.SetPath.html

    Assign a new path to this agent.

    If the path is succesfully assigned the agent will resume movement toward the new target. If the path cannot be assigned the path will be cleared (see ResetPath).

    It still linear, there is no path that is not linear, but you can play with angle velocity to smooth it.

    More that that, disable agent position update, just move agent and set NavMeshAgent.NextPosition = transform.position

    its all in docs
     
    Last edited: Nov 13, 2019
  4. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I can't create a new path with custom points.

    Maybe there's something to be done with nextPosition.. I'll try it out and let you know.
     
  5. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I would like to try not doing it this way but it will be my last resort if there is no other way.
     
  6. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    355
  7. FalconCK

    FalconCK

    Joined:
    May 6, 2015
    Posts:
    7
    If the distance to your target is very big, the SetDestination will not work, but to solve the problem I recommend you to use NavMeshPath, you can make a function to build a path and then move along it until you reach your target

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    public class TestAgentIA : MonoBehaviour
    {
    public Transform target;
    NavMeshAgent agent;
    NavMeshPath path ;
    private float elapsed = 0.0f;
    int index = 0;
    public bool DrawGizmo = false;
    public Color GizmoColor;
    public float radius;
    // Start is called before the first frame update
    void Start()
    {
    path = new NavMeshPath();
    agent = GetComponent<NavMeshAgent>();

    }

    // Update is called once per frame
    void Update()
    {


    elapsed += Time.deltaTime;
    if (elapsed > 1.0f)
    {
    elapsed -= 1.0f;
    NavMesh.CalculatePath(transform.position, target.position, NavMesh.AllAreas, path);
    index = 0;
    }
    MoveToPath();
    }
    void MoveToPath()
    {
    if (path != null && path.corners.Length > 0)
    {
    float distance = (path.corners[index] - transform.position).magnitude;
    if (distance <= agent.stoppingDistance)
    {
    index = (int)Mathf.Clamp(index+1, 0, path.corners.Length - 1);
    }
    agent.SetDestination(path.corners[index]);
    }
    }
    private void OnDrawGizmos()
    {
    if (!DrawGizmo|| path==null) return;
    Gizmos.color = GizmoColor;
    for (int i = 0; i < path.corners.Length - 1; i++)
    {
    Gizmos.DrawLine(path.corners, path.corners[i + 1]);
    if (index != i && index != i + 1)
    {
    Gizmos.DrawSphere(path.corners, radius);
    Gizmos.DrawSphere(path.corners[i + 1], radius);
    }

    }
    Gizmos.color = Color.blue;
    Gizmos.DrawSphere(path.corners[index], radius);
    }
    }