Skip to main content

VRChat Udon DataToken&VRCJson 食用指南

VRChat Udon DataToken&VRCJson 食用指南


VRC JSON

VRChat Json官方解释链接

 

概念解释

 

Json——数据格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,我们可以通过VRCJson反序列化来将其转换成DataToken,相对的也可以通过序列化为符合Json标准数据格式的Json文件。

 

DataToken——数据令牌

数据令牌会储存数据——每个 token 存储一个且仅存储一个变量。一般我们不会直接使用DataToken的定义,而是将其转换为字典或者列表来使用。额外的使用方式我们在这里不作详细解释,需要详细请访问DataToken


DataDdictionaries——数据字典

数据字典是一种特殊的数据令牌使用方式。我们可以通过一个String值作为“键”来提取内部储存的数据。我们可以通过一段小代码来形容。

public DataDictionary DefectData;

public void NewDictionary()
{
  //新建字典
  DefectData = new DataDictionary;
}

public void AddDictionary()
{
  //新建一个数据字典——键名为Key 数据为String类型的Value
  DefectData.Add("Key", "Value");
  //新建一个数据字典——键名为Key 数据为String类型的1234
  DefectData.Add("Int", "1234");
}

public void LoadValue()
{
  //尝试读取键名为Key下DataToken数据
  DefectData.TryGetValue("Key", out DataToken DataString);
  //将DataToken转换为String值
  String StringValue = DataString.Sting;

  //尝试读取键名为Int下DataToken数据
  DefectData.TryGetValue("Int", out DataToken DATAInt);
  //将DataToken转换为String值,然后通过TryParse转换为Int值
  int IntValue = DATAInt.Int;
}

在上文中,我们通过NewDictionary事件新建了一个数据字典

请注意——DataToken类的东西都需要在运行时执行初始化。

然后我们通过AddDictionary事件为新建的字典写入了两个键名以及对应的数据,键名分别是Key以及Int。

我们可以观察得到,基本来说Dictionary是通过一个String值作为键名储存一个数据。需要注意的是,实际上DataToken是可以储存Object类型,然后再Object类中继续封装多个数据,但是一旦存储了Object类的数据,将会导致这个字典无法序列化为Json。

再然后我们通过LodeValue事件来尝试读取新加入的数据,我们可以通过调用TryGetValue(键名,输出到的数据令牌)来获取数据

对于DataToken转换为具体数值,我们拥有两种方法

1:通过Tostring得到String值之后再通过TryParse来进行转换

优点:稳定不宜爆炸,可以设置多个代码来保护代码安全,所有可以通过这个方法提取数据的DataToken都肯定可以被序列化

缺点:复杂且看上去奇奇怪怪

2:直接通过DataToken.类型的方式来提取

优点:最正确的提取方式,最应该使用的方法

缺点:类型不正确直接爆炸,安全性约等于0。

 

让我们来看看字典转换为Json之后的样子

{
		"Name": "关闭系统",
		"Info": "关闭系统",
		"VoidNameID": 0,
		"CameraTrackingTarget": 0,
		"DisPlayName": "",
		"Slarp": false
},

这个字典中一共储存了三个String值,一个Int值以及一个Bool值。这个是我实际写的程序跑出来的Json,所以可以理解为这个就是VRC。

DataList——数据列表


DataList类似于数组,我们可以通过Index来按照顺序提取List中的数据。

让我们先观察一下数据列表的Json表达方式

[
	{
		"Name": "关闭系统",
		"Info": "关闭系统",
		"VoidNameID": 0,
		"CameraTrackingTarget": 0,
		"DisPlayName": "",
		"Slarp": false
	},
	{
		"Name": "特殊自由模式-1",
		"Info": "1",
		"VoidNameID": 5,
		"CameraTrackingTarget": 1,
		"DisPlayName": "",
		"Slarp": false
	}
]

我们可以看到,这个列表是由两个字典组成的,其中键名为Name,内容为“关闭系统”的字典位于顶部,而键名为Name,内容为“特殊自由模式-1”的字典位于第二位。

 

在序列化后,DataList将会将这两者都序列化,包括后面的字典也会序列化,咱们稍后再谈。这两个字典在序列化的时候,将会根据从上到下的顺序为他们设置Index索引值,第一个被序列化的字典将会是Index = 0 ,第二个则为Index = 1 让我们看看我们应该如何读取DataList。

public DataList List;

public void NewList()
{
  //新建字典
  List = new DataList;
}

public void AddDictionary()
{
  //新建一个数据列表,由于是第一个,所以Index为0
  List.Add(“Index0”);
  //新建一个数据列表,由于是第而个,所以Index为1
  List.Add(“Index1”);
    
}

public void LoadValue()
{
  List.TryGetValue(1, out var Token);
  string Index0 = Token.string
  List.TryGetValue(2, out var Token1);
  string Index1 = Token1.string
}

我们可以看到DataList的提取数据的方式是通过Index直接提取的。类似于数组,自然我们也可以通过For循环的方式将List中的数据全部提取出来。通常使用方式下,一般会考虑列表和词典进行组合。

 

通常使用方法:

通常时候,我们会通过List+Ddictionarie的方式来进行Json的构建。List可以保证我们可以通过顺序存储信息,而字典可以保证我们储存的信息各自拥有固定的访问方法不会错乱。正如数据列表栏目中的演示用的Json一样。当然我们直接通过构造Object来储存也能实现一样的效果,但是介于Object无法序列化,所以还是用通常方式来好一点。

 

VRCJson转DataToken相关