我正试图序列化一个二维字符串数组并通过网络发送。
我有几个想法,但我似乎被api或效率挡住了......我真的不想把一个小的二维数组序列化并通过网络发送10次。
我有一个玩家购物车里的物品列表,我想让玩家可以从购物车里偷东西,这样其他玩家就可以看到购物车里的东西了,如果我使用onphotonserializeview,我想我可以用delimeter和stream.sendnext将二维字符串数组转换为一维字符串数组。
如果我使用onphotonserializeview,我想我可以把二维的字符串数组转化为一维的字符串数组,再加上delimeter和stream.sendnext的delimeted行,然后在另一边重组......这种功能的一些变化。
public void serialize_merchandise_list() {
int width = 0;
int length = 0;
while((width < cart_list_width) && (length < cart_list_width)) {
width++;
if (width >= cart_list_width) {
length++;
width = 0;
}
// convert to bytes and then to string and append
System.Text.ASCIIEncoding.ASCII.GetBytes(merchandise_items[width, length]));
}
}
但这样做是不必要的,是操作时间上的噩梦......我想按需操作......。
我打算做一个punrpc,但我无法得到一个返回值或参考参数。
建议?
我想
与推车相撞 --> 是 --> 显示列表
你想从车上偷东西吗 --> 是 --> 显示列表
否则--> 走你的婚姻之路。
一个一维的字符串数组将是......。对光子来说没有问题.
所以我想你可以将数组扁平化,并额外发送第二个大小--让我们将它命名为元素大小(与第一个相反--元素数)作为参数。
例如,让我们说你的数组看起来像
string[,] array2D = new string[4,2]{{"a", "b"}, {"c","d"}, {"e","f"}, {"g","h"}};
那么你就会知道第二个(元素大小)维度,使用硬编码或 GetLength(int)
var elementSize = array2D.GetLength(1);
然后您可以使用
string[] arrayFlat = array2D.Cast<string>().ToArray();
所以,你会通过光子发送这两个信息(我对光子的细节不了解),但fafaik你可以做到这一点,而不必持续发送。这两个参数将是
int elementSize, string[] arrayFlat
在这种情况下,其数值为
2, string[8]{"a","b","c","d","e","f","g","h"}
所以在一起。
public void SendArray2D()
{
int elementSize = array2D.GetLength(1);
string[] arrayFlat = array2D.Cast<string>().ToArray();
photonView.RPC(nameof(ReceiveArray2D), RpcTarget.All, elementSize, (object) arrayFlat);
}
然后在接收器部分你会得到
int elementSize = 2, string[] arrayFlat = string[8]{"a","b","c","d","e","f","g","h"}
并要把它转换回来。你已经知道第二维度 elementSize = 2
所以,为了得到第一个,你只需做到
var elementCount = arrayFlat.Length / elementSize; // = 4
所以你知道你要填充的2D数组将是
string[,] array2D = new string[elementCount, elementSize]; // = 4,2
然后你就可以简单地迭代它,做一些类似于
for (var x = 0; x < elementCount; x++)
{
for (int y = 0; y < elementSize; y++)
{
array2D[x, y] = arrayFlat[x * elementSize + y];
}
}
所以在一起
[PunRpc]
public void ReceiveArray2D(int elementSize, string[] arrayFlat)
{
var elementCount = arrayFlat.Length / elementSize;
array2D = new string[elementCount, elementSize];
for (var x = 0; x < elementCount; x++)
{
for (int y = 0; y < elementSize; y++)
{
array2D[x, y] = arrayFlat[x * elementSize + y];
}
}
// Could also e.g. call some event like
OnReceivedArray2D?.Invoke (array2D);
}
public event Action<string[,]> OnReceivedArray2D;
所以你可以通过以下方式将监听器附加到事件上
reference.OnReceivedArray2D += SomeHandler;
private void SomeHandler(string [,])
{
// ...
}
或者你也可以实现一个类,将你的数据存储在一个平面数组中,但让你像访问一个二维数组一样访问它(一般来说,二维数组是作为一个平面数组存储在内存中的)。
[Serializable]
public class SerializableArray2D
{
public readonly string[] ArrayFlat;
public readonly ElementSize;
public SerializableArray2D(int elementSize, string[] arrayFlat)
{
ElementSize = elementSize;
ArrayFlat = arrayFlat;
}
public SerializableArray2D(string[,] array2D) : this(array2D.GetLength(1), array2D.Cast<string>().ToArray()) { }
public SerializableArray2D(int elementSize, int elementCount) : this(elementSize, new string[elementCount]){}
public string this[int x, int y]
{
get { return ArrayFlat[x * ElementSize + y]; }
set { ArrayFlat[x * ElementSize + y] = value; }
}
}
用法是例如:Initialize it。
var array2D = new string[4,2]{{"a", "b"}, {"c","d"}, {"e","f"}, {"g","h"}};
var serializableArray2D = new SerializableArray2D(array2D);
用于访问特定的指数,比如在一个2D数组中。
string example = serializableArray2D[1,1];
serializableArray2D[3,0] = "example";
为了发送它
photonView.RPC(nameof(Receive), RpcTarget.All, serializableArray2D.ElementSize, (object)serializableArray2D.ArrayFlat);
而当收到它时
[PunRPC]
public void Receive(int elementSize, string[] arrayFlat)
{
serializableArray2D = new SerializableArray2D(elementSize, arrayFlat);
// Again e.g. call an event
OnReceivedSerializableArray2D?.Invoke(serializableArray2D);
}
public event Action<SerializableArray2D> OnReceivedSerializableArray2D;