시작하기

값을 바이트로, 타입을 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;
    }
}

숫자는 .Int가 아니라 반드시 .Double로 읽으세요. 정수로 적었더라도 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, 그보다 단순한 것은 스칼라 토큰으로 대응합니다.

다음으로 읽을 것

레퍼런스는 양쪽 모두의 전체 멤버 목록입니다.

문제가 발생했습니다 새로 고침