我正在创建一个RPG游戏,我需要使用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";
}
}
}
是否有更好的方法来存储Tiled地图元数据?还是有更好的方法通过管道导入它?还是我的内容导入程序有问题?
答案 0 :(得分:1)
该错误归因于dynamic
类型。管道要求所有类型都可以通过反射解析和实例化。
有一个用于通用集合的辅助解析器,用于序列化和反序列化通用中的每种类型。行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
将其反序列化为Game1的Initialize
方法中的对象。