c# - MonoGame - 通过内容管道加载 JSON
问题描述
我正在创建一个 RPG 游戏,我需要使用 Tiled 加载地图。我有 Tiled 部分(我正在使用MonoGame.Extended
)。但我需要关于地图的额外数据。我的计划是使用包含必要信息的 JSON 文件。但是,我希望通过内容管道获得它,因为它与瓦片地图直接相关。
我尝试使用自定义内容管道扩展。它用于JSON.Net
将 JSON 文件反序列化为Dictionary<string, dynamic>
. 但是,当我编译 DLL 文件并尝试将其引用到管道工具中时,管道工具总是会崩溃。
内容导入器:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework.Content.Pipeline;
using Newtonsoft.Json;
namespace JsonExtension
{
[ContentImporter(".json", DefaultProcessor = "JsonProcessor")]
public class JsonImporter : ContentImporter<Dictionary<string, dynamic>>
{
public override Dictionary<string, dynamic> Import(string filename, ContentImporterContext context)
{
context.Logger.LogMessage("Importing JSON file: {0}", filename);
using (var streamReader = new StreamReader(filename))
{
JsonSerializer serializer = new JsonSerializer();
return (Dictionary<string, dynamic>)serializer.Deserialize(streamReader, typeof(Dictionary<string, dynamic>));
}
}
}
}
内容处理器:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Content.Pipeline;
namespace JsonExtension
{
[ContentProcessor]
public class JsonProcessor : ContentProcessor<Dictionary<string, dynamic>, Dictionary<string, dynamic>>
{
public override Dictionary<string, dynamic> Process(Dictionary<string, dynamic> input, ContentProcessorContext context)
{
context.Logger.LogMessage("Processing JSON");
return input;
}
}
}
内容类型作家:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Newtonsoft.Json;
namespace JsonExtension
{
[ContentTypeWriter]
class JsonTypeWriter : ContentTypeWriter<Dictionary<string, dynamic>>
{
protected override void Write(ContentWriter output, Dictionary<string, dynamic> value)
{
output.Write(JsonConvert.SerializeObject(value));
}
public override string GetRuntimeType(TargetPlatform targetPlatform)
{
return typeof(Dictionary<string, dynamic>).AssemblyQualifiedName;
}
public override string GetRuntimeReader(TargetPlatform targetPlatform)
{
return "JsonExtension.JsonReader";
}
}
}
有没有更好的方法来存储平铺地图元数据?还是有更好的方法通过管道导入它?还是我的内容导入器做错了什么?
解决方案
错误是由dynamic
类型引起的。管道要求所有类型都可以通过反射进行解析和实例化。
Generic 集合有一个辅助解析器,用于对 Generic 中的每种类型进行序列化和反序列化。该行Dictionary<string, dynamic>
有两种类型 和 与不可知类型相关联System.Collections.Generic.Dictionary
,System.String
和dynamic
。没有关于使用什么类型的dynamic
提示,并且无法解决导致错误。
简单的解决方案是将数据存储为 json 字符串(除了您尝试将其存储在的类型之外,您现在已经在执行此操作),并在返回数据后将其dynamic
反序列化String
到其对象中。Content.Load
换句话说Dictionary<string, string>
,用作内容处理器类型。
一个更简单的解决方案是将JSON
文件复制到输出目录。构建动作“如果较新则复制”并使用 System.IO.File 读取它并将JSON.NET
其反序列化为Initialize
Game1 方法中的对象。
推荐阅读
- android - 当上一个频道的视频在 android 应用程序的 youtube 视图中播放完时,如何自动播放来自其他频道的视频
- c - MISRA 2012 违规 - 类型不匹配(规则 10.1、10.4)
- r - R:纯固定效应模型中 sigma 的置信区间
- php - PHPMyAdmin 导出的数据库小于 PHPMyAdmin 控制面板中的数据库大小
- c# - 如何获取在 Roslyn 的 using 语句中声明的变量的类型
- node.js - 使用文件的内容而不用 express.js 保存文件?
- mysql - SQL插入专业化表
- gnuplot - 从同一行数据文件上的点画一条线
- android - Android Firebase 实时数据库:addListenerForSingleValueEvent 没有被触发
- java - 切换数据源和选择模式时是否存在 Hibernate 多租户开销