You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何将JSON对象转换为Godot原生Dictionary?解决赋值报错问题

解决Godot中JSON转Dictionary的报错问题

你遇到的问题根源是:直接把JSON文本存成.tres资源,Godot不会自动将其转换为Dictionary类型——.tres是Godot专属的资源序列化格式,直接存放JSON内容的话,加载出来的是原始文本或不符合类型要求的对象,自然会触发类型不匹配报错。

下面给两种实用的解决方法:

方法一:直接加载并解析JSON文件(推荐)

把卡牌数据保存为标准的.json文件,用Godot内置的JSON类解析成Dictionary:

修改你的代码如下:

extends Node

var card_data: Dictionary = {}

func _ready() -> void:
    # 打开JSON文件读取内容
    var file = FileAccess.open("res://singletons/database/card_details.json", FileAccess.READ)
    if file:
        var json_text = file.get_as_text()
        file.close()
        # 解析JSON字符串为Dictionary
        var parse_result = JSON.parse(json_text)
        if parse_result.error == OK:
            card_data = parse_result.result as Dictionary
        else:
            print("JSON解析失败: ", parse_result.error_string)
    else:
        print("无法找到或打开JSON文件")

func get_random_card(category: String) -> Dictionary:
    # 先判断分类是否存在,避免报错
    if category not in card_data or card_data[category].empty():
        return {}
    var cards_in_category: Array = card_data[category]
    var random_key: int = randi() % cards_in_category.size()
    return cards_in_category[random_key]

方法二:将JSON转为Godot资源后保存为.tres

如果一定要用.tres格式,需要先把JSON解析成Dictionary,再存入Godot资源对象后保存:

第一步:临时脚本生成.tres资源

先写一段临时代码,运行一次生成正确的.tres文件:

func _ready() -> void:
    # 读取原始JSON文件
    var file = FileAccess.open("res://card_details.json", FileAccess.READ)
    var json_text = file.get_as_text()
    file.close()
    # 解析为Dictionary
    var parse_result = JSON.parse(json_text)
    var card_dict = parse_result.result as Dictionary
    
    # 创建Resource对象存储字典
    var resource = Resource.new()
    resource.set_meta("card_data", card_dict)
    # 保存为.tres资源
    ResourceSaver.save(resource, "res://singletons/database/card_details.tres")
    print(".tres资源生成完成")

第二步:修改原加载代码

生成.tres后,修改你的原脚本:

extends Node

var card_data: Dictionary = {}

func _ready() -> void:
    var resource = preload("res://singletons/database/card_details.tres")
    card_data = resource.get_meta("card_data") as Dictionary

func get_random_card(category: String) -> Dictionary:
    if category not in card_data or card_data[category].empty():
        return {}
    var cards_in_category: Array = card_data[category]
    var random_key: int = randi() % cards_in_category.size()
    return cards_in_category[random_key]

注意事项

  • 确保你的JSON文件格式完全正确,比如引号使用、逗号分隔、括号配对等,否则会解析失败;
  • 如果使用Godot 3版本,把FileAccess换成File类,API用法略有不同;
  • 方法一更直接,适合大多数场景,方法二适合需要和其他Godot资源统一管理的情况。

内容的提问来源于stack exchange,提问作者Na N

火山引擎 最新活动