Skip to content

方便蓝图解析Json,通过Json中键所在层级,直接获取键和键值

Notifications You must be signed in to change notification settings

FHangH/UnrealReadJson

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unreal Read Json

有别于常见的UE中处理Json的方式,灵感来源于GameplayTagUE JsonObject中存储键值的方式:TMap<FString, TSharedPtr<FJsonValue>> Values;

UE中常见的解决方案:

  1. VaRest Plugin:在蓝图中将Json字符串转成JsonObject,然后就是ToValue ToObject HasFiled等繁琐的操作
    • 优点:执行效率高
    • 缺点:遇到多层次嵌套的JsonObject,你将在蓝图中亲手织出一个盘丝洞
  2. JsonToStruct:这种方案,就是用C++或蓝图,创建一个和Json完全一致的结构,甚至大小写也有影响数据解析的正确性
    • 优点:方案优雅,效率高,易维护
    • 缺点:遇到复杂的Json结构,需要创建N多个不同的结构体,也不是很方便

于是,我就在想,有没有一种可能,牺牲一些什么,换来一些什么?

恰好最近一直在学习UE GAS部分的内容,感受到GameplayTag作为逻辑的条件判断,非常的优雅和灵活,所以就模仿使用GameplayTag的方式,写了这个插件

优点:

  • 通过类型GameplayTag的方式,定位到Json中值
  • 不用在蓝图中织网了
  • 减少专门创建一堆结构体去JsonToStruct

缺点:

  • 也就内存占用大了一点点
  • 也就消耗大了那么一点点
  • 纯粹写着玩的!!!

0. 大致介绍

  1. 利用UE Json库,将Json字符串,依照Json中的键值,一对对的解析到TMap
  2. 遇到值为JsonObject,就迭代解析

遗憾:

  • 考虑到复杂庞大的Json结构中,可能存在很多层的数组嵌套,所以我的选择是遇到值为Array,就将整个Array作为字符串作为解析值
  • 如果需要解析数组的内容,需要单独使用另一个蓝图节点
  • 如果数组内的元素是:
    • int, float, int, string就可以直接得到数组内的值
    • object, array则不会迭代解析,直接将整个元素作为字符串存在StringArray
  • 总之,通过组合使用ReadJson_Async, GetNodeDataParseJsonArray这两个节点,就可以解析整个Json中的任意内容

注意:

  • Json数组内的元素必须一致

  • 不能出现这种情况:

    [1, 2.2, "123", {key: value}, [1, 2, 3]]
    
  • 这种的就没法使用这两个通用节点去解析了,只能自行处理了

1. 蓝图节点

image-20241220142400638

ReadJson_Async

  • 解析Json,将里面的键值对按照路径进行迭代,存入ParsedData
  • 实际使用时,建议将ParsedData存入变量中

GetNodeData

  • NodePath就是你需要的键值所在的路径

    {
        "1":
        {
            "2":"123"
        }
    }
  • GetNodePath("1.2")就可以得到NodeData

    {
        "Key":"2",
        "Value":
        {
            "StringValue":, // 这里可以获得 123
            "BoolValue":,
            "IntValue":,
            "FloatValue":
        }
    }

ParseJsonArray

  • 用于解析由Array转成的字符串,如果数组元素是:Array, Object ,则会将它们转成字符串存入StringArray

  • 例如:传入字符串到ParseJsonArray

    [
            {"name": "Google", "url": "www.google.com"},
            {"name": "Runoob", "url": "www.runoob.com"},
            {"name": "Taobao", "url": "www.taobao.com"}
    ]
  • 得到结构体ArrayValue

    {
        "StringArray":, // 如果带解析的数组内元素是:String, Array, Object,结果都在这里
        "BoolArray",
        "IntArray",
        "FloatArray"
    }

考虑到数组元素是:Array, Object ,则会将它们转成字符串存入StringArray

如果需要进一步解析:按照数组内元素的类型,重复使用下来的节点

  • Array使用ParseJsonArray
  • Object使用ReadJson_Async

2. 使用示例

测试 Json

{
    "name": "网站",
    "num": 3,
    "sites": 
    [
        {"name": "Google", "url": "www.google.com"},
        {"name": "Runoob", "url": "www.runoob.com"},
        {"name": "Taobao", "url": "www.taobao.com"}
    ],
    "testBool": true
}
{
    "array":
    {
        "int": [1, 2, 3],
        "string": ["a", "b", "c"],
        "bool": [true, false, true],
        "float": [1.1, 2.2, 3.3],
        "double": [1.1, 2.2, 3.3],
        "object": [{"name": "a"}, {"name": "b"}, {"name": "c"}],
        "array": [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    }
}
{
    "1":
    {
        "2":
        {
            "3":
            {
                "4": "123456789"
            }
        }
    }
}

image-20241220144559588

image-20241220144944843

image-20241220145543759

image-20241220145756200

image-20241220145921835

image-20241220150231254

3. 新增便捷蓝图节点

image-20241221171033626

3.1 GetNodeValue_To [ String, Int, Float, Bool ]

如果明确直到对应的Node Value的类型,可以直接使用这个系列的蓝图节点,比GetNodeData更简洁

3.2 ParseJsonArray_To [String, Int, Float, Bool] Array

测试Json1

{
    "array":
    {
        "int": [1, 2, 3],
        "string": ["a", "b", "c"],
        "bool": [true, false, true],
        "float": [1.1, 2.2, 3.3],
        "double": [1.1, 2.2, 3.3],
        "object": [{"name": "a"}, {"name": "b"}, {"name": "c"}],
        "array": [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    }
}

如果明确知道,对应的Node Value的值是Array,可以直接用这个蓝图节点,更便捷;

注意:如果Array的元素是Object,会将Object解析成String,如果需要进一步解析,使用:ReadJson_Async

3.3 GetNodeValue_To [String, Int, Float, Bool] Array

就是将 GetNodeValue_ToStringParseJsonArray_To[]Array节点结合使用;

例如想要得到Json2中的array.object,直接使用GetNodeValue_ToStringArray,就可以直接得到 TArray<FString>

其它依次类推

About

方便蓝图解析Json,通过Json中键所在层级,直接获取键和键值

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published