参考文档

ByteWriter、ByteReader、Json、IJsonSerializable 的所有成员。

更新于 2026-09-11

全部位于 Udonite.Serialization

ByteWriter

new ByteWriter()             // 默认初始容量
new ByteWriter(64)           // 以字节为单位的初始容量,需要时会继续增长
成员 写入内容
WriteByte(byte) 一个字节
WriteBoolean(bool), WriteChar(char) 固定长度
WriteInt16, WriteUInt16, WriteInt32, WriteUInt32, WriteSingle, WriteDouble 固定长度,基于 System.BitConverter
WriteString(string) 带长度前缀(null 记为 0),逐字符写入
WriteBytes(byte[]) 带长度前缀的原始字节——嵌套负载经由此处传递
WriteVector2, WriteVector3, WriteQuaternion 逐分量写入
WriteLength(int) 用尽可能少的字节表示一个数量——127 以内 1 字节,16383 以内 2 字节
Position { get; } 目前已写入的字节数
Reset() 不重新分配缓冲区,直接回退到空
ToArray() 恰好大小的拷贝——多分配出来的尾部不包含在内

所有 Write 方法都返回 this,可以链式调用:new ByteWriter().WriteInt32(1).WriteString("a")

刻意收窄的核心,不是 System.BitConverter 的完整照搬。 没有 64 位整数,没有带符号的 8 位,没有比 short 更窄的 16 位,也没有 Vector2Int。一个 reached 的类会被整体编译进去,声明的每个方法都会在程序存活期间一直占用堆——这里只保留负载真正可能携带的那些类型。

ByteReader

new ByteReader(bytes)
成员 读取内容
ReadByte() 一个字节
ReadBoolean(), ReadChar() 固定长度
ReadInt16, ReadUInt16, ReadInt32, ReadUInt32, ReadSingle, ReadDouble 固定长度
ReadString() 读回一个 WriteString 负载
ReadBytes() 读回一个 WriteBytes 负载
ReadVector2, ReadVector3, ReadQuaternion 逐分量读取
ReadLength() 读回一个 WriteLength 数量
Position { get; }, Length { get; }, LengthRemaining { get; } 游标位置、缓冲区大小、剩余字节数
SetBuffer(byte[]) 在另一个缓冲区上复用这个 reader,游标重置到开头

读到缓冲区末尾之外不会抛异常,而是打日志并返回该类型的默认值。 异常处理在 Udonite 里还未经验证,一个损坏或被截断的缓冲区不应该把读取它的 behaviour 一起拖垮。请按写入时的顺序读取,并读完你写入的全部内容——这里没有任何东西能告诉你格式错了,只能告诉你读取因为字节不够而停下了。

Json

成员 作用
Serialize<T>(T) 通过 T 自己的 ToJson() 把它打包成 JSON。T 为 null 或 VRCJson 拒绝时返回 null
Deserialize<T>(string) 解析 JSON,构造一个新的 Twhere T : class, IJsonSerializable, new()),通过 FromJson 填充它。JSON 不合法时返回 null
Serialize(DataToken), Serialize(DataToken, bool pretty) 低层形式,用于没有固定类型、临时拼装的 JSON
Deserialize(string) 直接返回一个 DataToken?,同一条逃生通道的反方向

失败时统一返回 null,而不是 boolout 参数的组合。

没有会遍历任意类型字段的、基于反射的 Serialize<T> Udon 完全没有反射——这是直接对着编译器验证过的事实,不是猜测。Deserialize<T>where T : new() 也不是反射:它是 C# 编译器在调用处解析的约束,所以即便这里没法调用 Activator.CreateInstance,它照样能编译通过。

每一个 JSON 数字都会被解析成 TokenType.Double,哪怕写的是一个普通整数。 {"score": 42} 解析出来的 token,.Int 会在上面抛异常——只有 .Double(再转换成你需要的类型)能读出来。这是 VRCJson 自身的特性,这个封装改变不了。

IJsonSerializable

成员 作用
DataToken ToJson() 把这个实例打包起来,通常打包成 DataDictionary
void FromJson(DataToken token) ToJson 产生的内容填充这个实例

两个方法都没提到的字段,既不会被发送,也不会被填充——这里没有任何机制会自动检查一个类型的成员。FromJson 修改的是被调用的那个实例本身,而不是返回一个新实例,这和 Udonite Net 里 NetworkEvent.Deserialize 的做法一样:这里要么需要 new(),要么需要调用方已经准备好一个实例,否则就没有办法构造出任意类型。

出了点问题 重新加载