C# 在光子单位中序列化Vector3d数据类型
我想在PUN RPC参数中使用vector3d数据类型,但光子不接受vector3d。我们需要注册并序列化它,以便在RPC方法中使用。我对序列化代码有一些问题C# 在光子单位中序列化Vector3d数据类型,c#,unity3d,serialization,photon,C#,Unity3d,Serialization,Photon,我想在PUN RPC参数中使用vector3d数据类型,但光子不接受vector3d。我们需要注册并序列化它,以便在RPC方法中使用。我对序列化代码有一些问题 namespace VoxelPlay { internal static class MyCustomDataType { internal static void Register() { PhotonPeer.RegisterType(typ
namespace VoxelPlay
{
internal static class MyCustomDataType
{
internal static void Register()
{
PhotonPeer.RegisterType(typeof(Vector3d), (byte)'V', SerializeVector3d, DeserializeVector3d);
}
public static readonly byte[] memVector3d = new byte[3 * 4];
private static short SerializeVector3d(StreamBuffer outStream, object customobject)
{
Vector3d vo = (Vector3d)customobject;
int index = 0;
lock (memVector3d)
{
byte[] bytes = memVector3d;
Protocol.Serialize(vo.x, bytes, ref index); //Getting error: Cannot convert from double to short
Protocol.Serialize(vo.y, bytes, ref index);
Protocol.Serialize(vo.z, bytes, ref index);
outStream.Write(bytes, 0, 3 * 4);
}
return 3 * 4;
}
private static object DeserializeVector3d(StreamBuffer inStream, short length)
{
Vector3d vo = new Vector3d();
lock (memVector3d)
{
inStream.Read(memVector3d, 0, 3 * 4);
int index = 0;
Protocol.Deserialize(out vo.x, memVector3d, ref index);
Protocol.Deserialize(out vo.y, memVector3d, ref index);
Protocol.Deserialize(out vo.z, memVector3d, ref index);
}
return vo;
}
}
}
实际上,只(反)序列化short
、int
或float
但是,您可以轻松定义自己的双重
(反)序列化,例如使用和/或
请注意,您的数组无论如何都是错误的!A
我建议您使用sizeof
进行此类操作;)
或者一种可能稍微有效的方法是直接使用
Buffer.BlockCopy
来转换如下值
internal static class MyCustomDataType
{
internal static void Register()
{
PhotonPeer.RegisterType(typeof(Vector3d), (byte)'V', SerializeVector3d, DeserializeVector3d);
}
// Note: Your array had the wrong length anyway!
// double is not 4 but 8 bytes!
// Instead of magic numbers rather use sizeof in general
public const short ByteSize = 3 * sizeof(double);
public static readonly byte[] memVector3d = new byte[ByteSize];
public static readonly double[] doubles = new double[3];
private static short SerializeVector3d(StreamBuffer outStream, object customobject)
{
var vo = (Vector3d)customobject;
lock (memVector3d)
{
// Fill the doubles array
doubles[0] = vo.x;
doubles[1] = vo.y;
doubles[2] = vo.z;
// directly copy that array on the bytes level
Buffer.BlockCopy(floats, 0, memVector3d, 0, ByteSize);
outStream.Write(memVector3d, 0, ByteSize);
}
return ByteSize;
}
private static object DeserializeVector3d(StreamBuffer inStream, short length)
{
var vo = new Vector3d();
lock (memVector3d)
{
inStream.Read(memVector3d, 0, ByteSize);
// Just the other way round directly copy into the doubles array on byte level
Buffer.BlockCopy(memVector3d, 0, floats, 0, ByteSize);
vo.x = doubles[0];
vo.y = doubles[1];
vo.z = doubles[2];
}
return vo;
}
}
现在请允许我问一个问题:您真的需要具有双值的
Vector3d
基本上,Unity中的所有内容都使用float
,因此在某些情况下,您将失去精度。那么,为什么同步时还没有失去精度呢
而且afaik在Photon中具有内置支持,因此无需编写/维护自定义代码
作为替代,如果同步时丢失精度是可以的,但您仍然希望使用
Vector3d
,您可能只需要使用
Protocol.Serialize((float)vo.x, bytes, ref index);
Protocol.Serialize((float)vo.y, bytes, ref index);
Protocol.Serialize((float)vo.z, bytes, ref index);
对于接收,只需确保它使用float
版本
Protocol.Deserialize(out float x, memVector3d, ref index);
Protocol.Deserialize(out float y, memVector3d, ref index);
Protocol.Deserialize(out float z, memVector3d, ref index);
vo.x = x;
vo.y = y;
vo.z = z;
但是再说一遍,为什么不首先简单地使用
Vector3
,假设它像前面提到的那样直接受支持。我建议您尝试转换vo.x,vo.y,为了消除注释错误,将vo.z加倍。好的,我将尝试this@JesúsNarváez如果错误已经说明给定的double
无法转换为short
(方法所期望的类型),那么将(已经!)double
值转换为double
不会有多大帮助;)我通过提取x、y和z坐标,将vector3d数据类型转换为vector3,解决了这个问题。谢谢你的帮助。谢谢你的帮助。我正在开发一个体素游戏,我希望体素中心的数据类型是vector3d,在RPC的参数中传递。
Protocol.Deserialize(out float x, memVector3d, ref index);
Protocol.Deserialize(out float y, memVector3d, ref index);
Protocol.Deserialize(out float z, memVector3d, ref index);
vo.x = x;
vo.y = y;
vo.z = z;