快速开始

把一个值打包成字节,把一个类型打包成 JSON。

更新于 2026-09-11

打包成字节

ByteWriter 负责搭建缓冲区,ByteReader 按相同顺序读回来:

using Udonite.Serialization;

byte[] payload = new ByteWriter()
    .WriteInt32(playerId)
    .WriteString(name)
    .ToArray();

ByteReader reader = new ByteReader(payload);
int id = reader.ReadInt32();
string readName = reader.ReadString();

这两者在 Udonite Net 的消息指南 里有完整介绍——它们本来就是为那里而生的:NetworkEventSerialize(ByteWriter)/Deserialize(ByteReader)。不过它们本身并不专属于网络。只要你想要一种紧凑、自成一体、两端都由你掌控的二进制格式,用在哪里都行——存档格式,或者一个文件。

读到缓冲区末尾之外不会抛异常。 它会打日志并返回该类型的默认值,因为 Udon 没有异常处理可以回退,而一个损坏或被截断的缓冲区不应该把读取它的 behaviour 一起拖垮。

把类型打包成 JSON

一个类型通过实现 IJsonSerializable 来加入——自己写 ToJson()/FromJson(),因为 Udon 没有反射能替你做这种遍历。

using Udonite.Serialization;
using VRC.SDK3.Data;

public class Player : IJsonSerializable
{
    public string Name;
    public int Score;

    public DataToken ToJson()
    {
        DataDictionary dict = new DataDictionary();
        dict.Add("name", Name);
        dict.Add("score", Score);
        return dict;
    }

    public void FromJson(DataToken token)
    {
        DataDictionary dict = token.DataDictionary;
        Name = dict["name"].String;
        Score = (int)dict["score"].Double;
    }
}

数字要用 .Double 读,绝不能用 .Int 哪怕当初是作为整数写入的,JSON 数字解析回来时一律是 TokenType.Double——.Int 会在这里抛异常。这是 VRCJson 自身的特性,这个包没法替你掩盖。

序列化和反序列化的调用方完全不会碰到 DataToken

Player player = new Player { Name = "Ada", Score = 42 };

string json = Json.Serialize(player);          // {"name":"Ada","score":42},失败则为 null
Player restored = Json.Deserialize<Player>(json); // 一个新的 Player,JSON 有误则为 null

Deserialize<T> 会自己构造实例——T 需要一个无参构造函数(where T : new())。这是编译器在调用处解析的约束,而不是运行时的事,和其他泛型约束没什么两样。这不是反射,即便 Udon 完全没有反射,它照样能用。

没有任何东西会被自动检查。 ToJson() 没提到的字段永远不会被发送,一个完全没实现 IJsonSerializable 的类型对 Serialize<T> 来说就是编译错误——绝不会在运行时变成一个只序列化了一部分的对象。

组装没有固定类型的 JSON

对于临时拼装、背后没有 IJsonSerializable 的 JSON,有直接操作 DataToken 的非泛型重载:

DataDictionary dict = new DataDictionary();
dict.Add("ok", true);

string json = Json.Serialize(dict);          // 或 Json.Serialize(dict, pretty: true)
DataToken? parsed = Json.Deserialize(json);

这是唯一绕不开 DataToken 的地方,因为它就是 VRChat 自己的 JSON 值模型——对象对应 DataDictionary,数组对应 DataList,更简单的值对应标量 token。

接下来看什么

参考文档 是两边所有成员的清单。

出了点问题 重新加载