- Home /
Send a mesh via Network
I am trying to create a 3D Tron Game and i used the Trail Script from the unity examples and added a mesh collider to it, so I can collider with the Trail which works pretty good. Now I need to sync the mesh via network and I just find a solution to it. Since i cant send arrays via an RPC I would have to convert everything into a string, but then i get massive lags because of the huge amount of data.. any ideas?
Can you not download the meshes from a server? That would be faster. How are you creating your string right now?
it sounds like you certainly want to do something tremendously simpler
but for you or perhaps anyone who noticed the title, be sure to look at this really critical amazing fact ...
http://answers.unity3d.com/questions/190340/how-can-i-send-a-render-texture-over-the-network.html
note the "Important Note !!!!!!!!!!!!!!!!!!" in the second answer. Epic !
Answer by whydoidoit · Oct 18, 2012 at 08:43 PM
This would send a basic mesh through. You could expand if for materials etc. It's going to be big though, just not as big as your string.
using UnityEngine;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
public class SendMeshBehaviour : MonoBehaviour {
public static event Action<string, Mesh> GotNewMesh = delegate {};
[RPC]
void GetMesh(byte[] data)
{
var fmt = new BinaryFormatter();
var mem = new MemoryStream(data);
var md = fmt.Deserialize(mem) as MeshData;
var mesh = new Mesh {
vertices = md.vertices,
normals = md.normals,
triangles = md.triangles,
uv1 = md.uv1,
uv2 = md.uv2
};
mesh.RecalculateBounds();
GotNewMesh(md.name, mesh);
}
public class MeshData
{
public string name;
public int[] triangles;
public Vector3[] vertices;
public Vector2[] uv1;
public Vector2[] uv2;
public Vector3[] normals;
}
public void SendMesh(string name, Mesh mesh)
{
var mem = new MemoryStream();
var fmt = new BinaryFormatter();
fmt.Serialize(mem, new MeshData { triangles = mesh.triangles,
normals = mesh.normals,
vertices = mesh.vertices,
uv1 = mesh.uv1,
uv2 = mesh.uv2,
name = name
});
networkView.RPC("GetMesh", RPCMode.Others, mem.GetBuffer());
}
}
You will get a static event being raised whenever a mesh is received - obviously you could just handle the receiver call in a different way.
Send$$anonymous$$eshBehaviour.GotNew$$anonymous$$esh += HandleNew$$anonymous$$esh;
void HandleNew$$anonymous$$esh(string name, $$anonymous$$esh mesh)
{
//Do something
}
I eventually used the HoloLens Toolkits Simple$$anonymous$$eshSerialiser as the Windows HoloToolkit doesn't support some serialisation methods.
Still the amount of data being sent was to large so i ended up combining that with the CLZF compression script from the below link. link text
I also added a new Network$$anonymous$$anager channel with fragmented, to support a larger upper byte size limit.
public void Send$$anonymous$$esh(string name, $$anonymous$$esh mesh)
{
Debug.Log("Send$$anonymous$$eshData.Send$$anonymous$$esh()");
List<$$anonymous$$esh> meshesToSend = new List<$$anonymous$$esh>();
meshesToSend.Add(mesh);
byte[] data = Simple$$anonymous$$eshSerializer.Serialize(meshesToSend);
data = CLZF2.Compress(data);
CmdSend$$anonymous$$esh(name, data);
}
[Command(channel = 2)]
public void CmdSend$$anonymous$$esh(string name, byte[] meshData)
{
Debug.Log("Send$$anonymous$$eshData.Send$$anonymous$$esh()[Command]");
Rpc_Get$$anonymous$$esh(name, meshData);
}
[ClientRpc(channel = 2)]
void Rpc_Get$$anonymous$$esh(string name, byte[] data)
{
Debug.Log("Send$$anonymous$$eshData.Rpc_Get$$anonymous$$esh()[ClientRPC]");
data = CLZF2.Decompress(data);
List<$$anonymous$$esh> meshes = new List<$$anonymous$$esh>(Simple$$anonymous$$eshSerializer.Deserialize(data));
GotNew$$anonymous$$esh(name, meshes[0]);
}
Answer by Fattie · Oct 19, 2012 at 07:17 AM
Just FWIW,
on this actual question about the trail-tail..............
In a recent project when I literally send a mesh between two devices, I don't - instead, I send the thing that makes the mesh! (This concept would vary depending on what you're doing.)
In your case:
the trail (and hence the mesh) must be made in some way by some code that takes some starting input - for example, a series of positions of the object? Or perhaps a "velocity and position" ..?? Right?
In fact, just send that "series of positions" or "velocity and position" and run THE SAME CODE on the far side. Cross fingers, and it should produce the SAME RESULT.
The very best part about all this is not the huge efficiency, etc. The best part is that if it works you feel REALLY smug! :)
@Fattie Quite certainly the best thing to do if you can because it's incremental as the game progresses.
Oh.. Just tried it and it works perfect, such a simple solution. Thank you very much !
I've been trying to do this for more complex geometry. First I ran into the issue of packet length so I know for a fact im going to have to section the mesh down into chunks that are small enough to send. $$anonymous$$y biggest issue is the deconstruction and reconstruction of a mesh. For example I'm working from the vertices, trying to capture say 50 verts at once so i grab those and then check for any tris that include these verts, then out of those tris keep the ones where every vert is on the 50 verts list, because otherwise its a tri from a section i dont want just yet. i'm pretty positive this will cause me to lose some tris, but for now i'm just wanting the basics and can tackle that down the line.
A cannot for the life of me just take one section of vertices, extrapolate the tris that are being used and then rebuild a separate mesh of just those vertices and resulting tris.
Anybody try anything like this or able to help me out?
maybe i need to iterate through the tris and build lists from there (I could see this helping me not over look some tris)
This is extra but once i get each section i think it wont be too hard of an issue to build one mesh out of the sections ive seen that done before but again cannot find any example of someone just splitting a mesh into two separate meshes. Im guessing most of this is because the lists arent really in any top/down order they hop around.