add LdtkFieldInstance and LdtkEntityMap classes; update LdtkSceneBuilder to support entity mapping
This commit is contained in:
11
addons/csharp_ldtk_importer/LdtkEntityMap.cs
Normal file
11
addons/csharp_ldtk_importer/LdtkEntityMap.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace CSharpLdtkImporter;
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class LdtkEntityMap : Resource
|
||||
{
|
||||
[Export] public Dictionary<string, PackedScene> EntitySceneMap { get; set; } = new();
|
||||
}
|
1
addons/csharp_ldtk_importer/LdtkEntityMap.cs.uid
Normal file
1
addons/csharp_ldtk_importer/LdtkEntityMap.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c5wadsimbi1re
|
@@ -44,9 +44,11 @@ public partial class LdtkResourceImporter : EditorImportPlugin
|
||||
GD.PushError("Parsed LDTK data is null.");
|
||||
return Error.Failed;
|
||||
}
|
||||
|
||||
var entityMap = options.TryGetValue("entity_map", out var map) ? map.As<LdtkEntityMap>() : null;
|
||||
|
||||
// 3. Use the Scene Builder to generate the Godot scene
|
||||
var builder = new LdtkSceneBuilder(ldtkData, sourceFile);
|
||||
var builder = new LdtkSceneBuilder(ldtkData, sourceFile, entityMap);
|
||||
var rootNode = builder.BuildLdtkProjectRoot();
|
||||
|
||||
var scene = new PackedScene();
|
||||
@@ -78,6 +80,13 @@ public partial class LdtkResourceImporter : EditorImportPlugin
|
||||
{ "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" },
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using CSharpLdtkImporter.Models;
|
||||
using Godot;
|
||||
|
||||
@@ -8,12 +10,14 @@ public class LdtkSceneBuilder
|
||||
{
|
||||
private readonly LdtkData _ldtkData;
|
||||
private readonly string _basePath;
|
||||
private readonly LdtkEntityMap _entityMap;
|
||||
private readonly Godot.Collections.Dictionary<int, TileSet> _tileSetCache = new();
|
||||
|
||||
public LdtkSceneBuilder(LdtkData ldtkData, string sourceFile)
|
||||
public LdtkSceneBuilder(LdtkData ldtkData, string sourceFile, LdtkEntityMap entityMap)
|
||||
{
|
||||
_ldtkData = ldtkData;
|
||||
_basePath = sourceFile.GetBaseDir();
|
||||
_entityMap = entityMap;
|
||||
}
|
||||
|
||||
public Node2D BuildLdtkProjectRoot()
|
||||
@@ -94,17 +98,57 @@ public class LdtkSceneBuilder
|
||||
private Node2D BuildEntityLayer(LdtkLayerInstance layer)
|
||||
{
|
||||
var entityLayerRoot = new Node2D { Name = layer.Identifier };
|
||||
|
||||
foreach (var entity in layer.EntityInstances)
|
||||
{
|
||||
var marker = new Marker2D
|
||||
Node2D instance = null;
|
||||
|
||||
GD.Print($"EntityMap keys: {string.Join(", ", _entityMap?.EntitySceneMap.Keys ?? Array.Empty<string>())}");
|
||||
GD.Print($"Entity Identifier: {entity.Identifier}");
|
||||
GD.Print($"Is Entity Mapped: {_entityMap?.EntitySceneMap.ContainsKey(entity.Identifier)}");
|
||||
|
||||
if (_entityMap?.EntitySceneMap.TryGetValue(entity.Identifier, out var packedScene) == true &&
|
||||
packedScene != null)
|
||||
{
|
||||
Name = entity.Identifier,
|
||||
Position = new Vector2(entity.Px[0], entity.Px[1])
|
||||
};
|
||||
entityLayerRoot.AddChild(marker);
|
||||
GD.Print($"Instantiating entity '{entity.Identifier}' from mapped scene.");
|
||||
instance = packedScene.Instantiate<Node2D>();
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.Print($"Defaulting to Marker2D for unmapped entity '{entity.Identifier}'.");
|
||||
instance = new Marker2D();
|
||||
}
|
||||
|
||||
instance.Name = entity.Identifier;
|
||||
instance.Position = new Vector2(entity.Px[0], entity.Px[1]);
|
||||
|
||||
foreach (var field in entity.FieldInstances)
|
||||
{
|
||||
instance.SetMeta(field.Identifier, ConvertJsonElementToVariant(field.Value));
|
||||
}
|
||||
|
||||
entityLayerRoot.AddChild(instance);
|
||||
}
|
||||
|
||||
return entityLayerRoot;
|
||||
}
|
||||
|
||||
private static Variant ConvertJsonElementToVariant(JsonElement element)
|
||||
{
|
||||
return element.ValueKind switch
|
||||
{
|
||||
JsonValueKind.String => element.GetString(),
|
||||
JsonValueKind.Number => element.GetDouble(),
|
||||
JsonValueKind.True => true,
|
||||
JsonValueKind.False => false,
|
||||
JsonValueKind.Null => default,
|
||||
// For LDTK points (which are objects) or arrays, we can serialize them back to a JSON string.
|
||||
// A more advanced implementation could convert these to Vector2 or Array types.
|
||||
JsonValueKind.Object => Json.Stringify(Json.ParseString(element.GetRawText())),
|
||||
JsonValueKind.Array => Json.Stringify(Json.ParseString(element.GetRawText())),
|
||||
_ => default
|
||||
};
|
||||
}
|
||||
|
||||
private TileSet GetOrCreateTileSet(int tilesetDefUid)
|
||||
{
|
||||
|
@@ -9,4 +9,7 @@ public class LdtkEntityInstance
|
||||
|
||||
[JsonPropertyName("px")]
|
||||
public int[] Px { get; set; }
|
||||
|
||||
[JsonPropertyName("fieldInstances")]
|
||||
public LdtkFieldInstance[] FieldInstances { get; set; }
|
||||
}
|
16
addons/csharp_ldtk_importer/Models/LdtkFieldInstance.cs
Normal file
16
addons/csharp_ldtk_importer/Models/LdtkFieldInstance.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace CSharpLdtkImporter.Models;
|
||||
|
||||
public class LdtkFieldInstance
|
||||
{
|
||||
[JsonPropertyName("__identifier")]
|
||||
public string Identifier { get; set; }
|
||||
|
||||
[JsonPropertyName("__type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonPropertyName("__value")]
|
||||
public JsonElement Value { get; set; }
|
||||
}
|
@@ -0,0 +1 @@
|
||||
uid://dgwt3rdvkdypq
|
Reference in New Issue
Block a user