以下函数(或其一部分,我只会添加与问题相关的部分)应该从
.json
文件加载我正在制作的简单游戏引擎的 UI 配置(这都是自定义的) 。我正在使用现代 C++ 的 Nlohmann JSON 库。
void UIManager::loadUiConfig(SceneManager& sceneManager){
std::ifstream uiFile("..\\resources\\ui\\ui.json");
if(!uiFile.is_open()){
std::cerr << "Failed to load ui configuration file" << std::endl;
exit(EXIT_FAILURE);
}
json uiConfig;
try{
uiFile >> uiConfig;
}catch(const json::parse_error& e){
std::cerr << e.what() << std::endl;
exit(EXIT_FAILURE);
}
StructScenes scenesData;
try{
if(!uiConfig.contains("scenes")) throw std::runtime_error("scenes is not found");
if(uiConfig["scenes"].is_null()) throw std::runtime_error("scenes is empty/null");
scenesData = uiConfig.template get<StructScenes>();
} catch (const std::runtime_error& e) {
std::cerr << "Runtime Error: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}catch(const json::type_error& e){
std::cerr << "Error parsing JSON: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
//rest of function
}
这些是我定义的用于保存
.json
文件中的数据的结构:
#ifndef SERIALIZER_CLASS_H
#define SERIALIZER_CLASS_H
#include <glad/glad.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <EventHandler/EventType.h>
#include <Json/json.hpp>
#include <ui/ui.h>
struct StructAppearance{
GLfloat posX, posY;
GLfloat width, height;
GLfloat color[4];
GLfloat texturePosX, texturePosY;
std::string textureImagePath;
int renderType;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructAppearance, posX, posY, width, height, color, texturePosX, texturePosY, textureImagePath, renderType);
};
struct StructButton{
std::string name;
std::vector<std::pair<EventType, std::string>> events;
StructAppearance appearance;
Shapes shape;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};
struct StructScene {
std::string name;
std::vector<StructButton> sceneMembers;
std::string vertexShaderPath;
std::string fragmentShaderPath;
GLfloat backgroundColor[4];
int posSize, colorSize, texSize;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructScene, sceneMembers, vertexShaderPath, fragmentShaderPath, backgroundColor, posSize, colorSize, texSize);
};
struct StructScenes{
std::vector<StructScene> scenes;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructScenes, scenes);
};
#endif
入口结构(或根结构)是
StructScenes
,它只包含所有可用场景的std::vector<StructScene>
(这只是我在游戏中创建菜单的方法)。
问题出在我想要将
.json
数据反序列化到 StructScenes
的部分。它一直显示此错误:
解析 JSON 时出错:[json.exception.type_error.302] 类型必须是数组,但却是对象
具体来说,错误发生在这一行:
scenesData = uiConfig.template get<StructScenes>();
我尝试直接制作
std::vector<StructScene>
,但同样的问题发生在我收到上述错误的地方,而不是实际创建场景并用相应的按钮填充它们。
编辑:因为人们要求 ui.json 文件,这是我正在使用的示例:
{
"scenes": [
{
"name": "Main Menu",
"sceneMembers": [
{
"name": "Play",
"events": [
{
"type": "onclick",
"action": "settings"
}
],
"appearance": {
"posX": -0.9,
"posY": 0.1,
"width": 0.4,
"height": 0.3,
"color": [0, 0, 0, 0],
"texturePosX": 0,
"texturePosY": 0,
"textureImagePath": "..\\resources\\textures\\play.png",
"renderType": 1
},
"shape": "rectangle"
}
],
"vertexShaderPath": "..\\resources\\Shaders\\default.vert",
"fragmentShaderPath": "..\\resources\\Shaders\\default.frag",
"backgroundColor": [1.0, 1.0, 1.0, 1.0],
"posSize": 2,
"colorSize": 4,
"texSize": 2
}
]
}
根据您提供的 json 文件,
events
字段应该是一个对象数组
"events": [
{
"type": "onclick",
"action": "settings"
}
],
因此该结构体的
events
成员不正确
struct StructButton {
std::string name;
std::vector<std::pair<EventType, std::string>> events;
StructAppearance appearance;
Shapes shape;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};
它应该是另一个结构,它将是一个 json 对象
struct StructEvent {
std::string type;
std::string action;
};
然后您将更新 Button 成员
struct StructButton {
std::string name;
std::vector<StructEvent> events;
StructAppearance appearance;
Shapes shape;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};