using System.Text.Json; using CSharpLdtkImporter.Models; using Godot; using Godot.Collections; namespace CSharpLdtkImporter; [Tool] public partial class LdtkResourceImporter : EditorImportPlugin { public override string _GetImporterName() => "ldtk.importer"; public override string _GetVisibleName() => "LDtk Level Importer"; public override string[] _GetRecognizedExtensions() => new string[] { "ldtk" }; public override string _GetResourceType() => "PackedScene"; public override string _GetSaveExtension() => "tscn"; public override int _GetPresetCount() => 0; public override float _GetPriority() => 1.0f; public override Error _Import(string sourceFile, string savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles) { // 1. Read the .ldtk file content using var file = FileAccess.Open(sourceFile, FileAccess.ModeFlags.Read); if (file == null) { GD.PushError($"Failed to open LDTK file: {sourceFile}"); return Error.CantOpen; } string jsonContent = file.GetAsText(); // 2. Deserialize the JSON into our C# data models LdtkData ldtkData; try { ldtkData = JsonSerializer.Deserialize(jsonContent); } catch (JsonException e) { GD.PushError($"Failed to parse LDTK JSON: {e.Message}"); return Error.ParseError; } if (ldtkData == null) { GD.PushError("Parsed LDTK data is null."); return Error.Failed; } var entityMap = options.TryGetValue("entity_map", out var map) ? map.As() : null; // 3. Use the Scene Builder to generate the Godot scene var builder = new LdtkSceneBuilder(ldtkData, sourceFile, entityMap); var rootNode = builder.BuildLdtkProjectRoot(); var scene = new PackedScene(); scene.Pack(rootNode); // 4. Save the generated scene var destinationPath = $"{savePath}.{_GetSaveExtension()}"; var error = ResourceSaver.Save(scene, destinationPath); if (error != Error.Ok) { GD.PushError($"Failed to save generated scene to {destinationPath}"); } return error; } public override Array _GetImportOptions(string path, int presetIndex) { var options = new Array() { new() { { "name", "import_entities" }, { "default_value", true }, { "usage", (int)(PropertyUsageFlags.Default | PropertyUsageFlags.UpdateAllIfModified) } }, new() { { "name", "import_tilemaps" }, { "default_value", true }, { "usage", (int)(PropertyUsageFlags.Default | PropertyUsageFlags.UpdateAllIfModified) } }, new() { { "name", "entity_map" }, { "default_value", new LdtkEntityMap() }, { "property_hint", (int)PropertyHint.ResourceType }, { "hint_string", "LdtkEntityMap" }, } }; return options; } public override bool _GetOptionVisibility(string path, StringName optionName, Dictionary options) { return true; } }