VRChat Udon DataToken&VRCJson 食用指南
VRChat Udon DataToken&VRCJson 食用指南
VRC JSON
概念解释
Json——数据格式
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,我们可以通过VRCJson反序列化来将其转换成DataToken,相对的也可以通过序列化为符合Json标准数据格式的Json文件。
DataToken——数据令牌
数据令牌会储存数据——每个 token 存储一个且仅存储一个变量。一般我们不会直接使用DataToken的定义,而是将其转换为字典或者列表来使用。额外的使用方式我们在这里不作详细解释,需要详细请访问DataToken
DataDictionary——数据字典
数据字典是一种特殊的数据令牌使用方式。我们可以通过一个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+Dictionary的方式来进行Json的构建。List可以保证我们可以通过顺序存储信息,而字典可以保证我们储存的信息各自拥有固定的访问方法不会错乱。正如数据列表栏目中的演示用的Json一样。当然我们直接通过构造Object来储存也能实现一样的效果,但是介于Object无法序列化,所以还是用通常方式来好一点。