How can NavMeshPath be serialized in order to sync it across the network with other clients? Currently I’m using Vector3 positions and SetDestination, but this does not guarantee the same path on every client. Hence I’d like to use a path calculated on the server and sync that instead…
You could turn the Vector3 array into a list und use the SyncListStruct class to create the network syncable container:
https://docs.unity3d.com/ScriptReference/Networking.SyncListStruct_1.html
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!
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.
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 _= Utils.SerializeVector3(path.corners*); }*_
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 = Utils.DeserializeVector3(sPathCorners*); }*
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);
}
© 2022 - 2024 — McMap. All rights reserved.
@Sarawak NavMeshAgent.SetPath and NavMeshAgent.path only allow me to set a NavMeshPath, so how would I set the path with the Vector3 array?
– ThreapI have this exact question. Could you please clarify? @hexagonius
– Pontus