How to set NavMeshAgent Path with Vector3[]?

The server of my multiplayer game calculates a navmesh path for NPCs. This path is then synced over the network using a serialized Vector3 array obtained through NavMeshPath.corners. However, NavMeshAgent.SetPath and NavMeshAgent.path only allow me to set a NavMeshPath. The reason I want to sync the server generated navmesh path is, to ensure that all clients use the same path for the NPC characters. I could sync the new navmesh position and set it with NavMeshAgent.SetDestination, but that wouldn’t be practical regarding the “same path for all”.

  • So how would I set the path with the Vector3 array?
  • Or how can I create a NavMeshPath from the Vector3 array?
  • Or what’s another way of syncing the server calculated navmesh path?

Unity - Scripting API: AI.NavMeshPath.corners
Unity - Scripting API: AI.NavMeshAgent.SetPath
Unity - Scripting API: AI.NavMeshAgent.path
Unity - Scripting API: NavMeshPath
Unity - Scripting API: AI.NavMeshAgent.SetDestination

I did this for my Save & Load system (for NPC nav mesh paths), and I think it works OK, and I hope it might be useful to some other people out there. Or even give people a start on how to do it even better than my version! :slight_smile:

It’s a little bit chopped up to fit in the relevant stuff, without too much other guff. Hopefully, the useful bits are all there. :slight_smile:

These methods are in a UTILS SCRIPT (for serializing Vector3’s and things)

// you can't directly serialize a Vector3, so make a struct to store the relevant info
[System.Serializable]
public struct SerializedVector3
{
    public float x;
    public float y;
    public float z;
}

// this method converts a Vector3 into a SerializedVector3
public static SerializedVector3 SerializeVector3(Vector3 v3)
{
    SerializedVector3 sv3;
    sv3.x = v3.x;
    sv3.y = v3.y;
    sv3.z = v3.z;
    return sv3;
}

// this method converts a SerializedVector3 into a Vector3
public static Vector3 DeserializeVector3(SerializedVector3 sv3)
{
    Vector3 v3;
    v3.x = sv3.x;
    v3.y = sv3.y;
    v3.z = sv3.z;
    return v3;
}

// this method converts a path into an array of SerializedVector3's based on the path corners array.
public static SerializedVector3[] SerializeNavPath(NavMeshPath path)
{
    SerializedVector3[] pathCorners = new SerializedVector3[path.corners.Length];
    for (int i = 0; i < path.corners.Length; i++)
    {
        pathCorners[i] = Utils.SerializeVector3(path.corners[i]);
    }
    return pathCorners;
}

// this method converts the array of SerializedVector3's back into a normal Vector3 array, 
// then turns that into a path using the GetCornersNonAlloc method
public static NavMeshPath DeserializeNavPath(SerializedVector3[] sPathCorners)
{
    NavMeshPath path = new NavMeshPath();
    Vector3[] pathCorners = new Vector3[sPathCorners.Length];

    for (int i = 0; i < pathCorners.Length; i++)
    {
        pathCorners[i] = Utils.DeserializeVector3(sPathCorners[i]);
    }

    path.GetCornersNonAlloc(pathCorners);
    return path;
}

These methods are in my NPC script, for saving and loading the nav mesh path

// this method passes the path into my save & load system
public NPCData PrepareSaveDataForSelf()
{
    myNPCData.savedPath = Utils.SerializeNavPath(path);
    return myNPCData;
}

// this method takes the saved path, and turns it back into a nav mesh path
public void LoadEntityData()
{
    path = Utils.DeserializeNavPath(myNPCData.savedPath);
}

I have the same problem. I want to Calc the path on PC A and send it to B and C. PC A is the only one who is Calc, this is good for performance. But the only way i found out is to change the NavMeshPath.Corner readonly.

Have u found a better solution?

Has anyone found a solution for this?

@muzboz that solution no longer appears to work, the NavMeshPath is always empty