kiamo2 / yati Goto Github PK
View Code? Open in Web Editor NEWAddon to import Tiled maps into Godot 4
License: MIT License
Addon to import Tiled maps into Godot 4
License: MIT License
Describe the bug
When a .tsx tileset has tiles which contain custom boolean properties, those values aren't correctly imported as custom data layers, i.e. anything marked "true" will come through as false.
This is because TilesetCreator.gd
-> handle_tile_properties
, doesn't convert val
to the appropriate type before calling set_custom_data(name, val)
, so it will try to set a boolean to the string "true" which fails silently and leaves the value as false.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expect the boolean data to come through just like how ints and strings are working.
Screenshots
N/a
Desktop (please complete the following information):
Examle map (zipped)
I can provide one if the above information isn't clear enough.
Additional context
Here's my example hack that I've added immediately before the aforementioned current_tile.set_custom_data(name, val)
to fix the problem for bools specifically. I don't know if colors are working, but I assume that floats are working along with ints and strings.
if _tileset.get_custom_data_layer_type(custom_layer) == TYPE_BOOL: val = (val.to_lower() == 'true')
Additionally, there's a soon-to-be-fixed bug in Godot that can mess up what custom data layer name corresponds to what data due to the addition/removal of the internal CUSTOM_DATA_INTERNAL
data layer during the import process, which may complicate testing until it's closed.
using a custom property "resPath" with String value(path of tscn file). when imported, the tile object will be replaced by the tscn file.
Describe the bug
When importing a Tmx file with use_tilemap_layers
toggled, The properties in the "tilelayer" of Tiled, such as y_sort_enabled
, z_index
, which should be belong to the Layer of TileMap, are applied to TileMap by mistake.
To Reproduce
Steps to reproduce the behavior:
int
property z_index
(100) in the layer: tree
.Use Tilemap Layers
onz_index
property of the TileMap
(not the layer of TileMap), which is set to 100.Expected behavior
The z_index
property should be set on the tree
's layer.
Desktop (please complete the following information):
For a given tile map layer, how do I access the tile value for a particular tile?
MacOS Sonoma, Godot 4.1.
I'm new to Godot, so still finding my way - is there a node I need to add to enable tile anims? Couldn't find any mention of tile anims, other than they're supported.
Thanks!
Is your feature request related to a problem? Please describe.
When I use custom properties of type "object" I get a field in the metadata with the integer value of the ID of the linked object. I don't think the object IDs are imported. At least, I have not found a place where the object IDs are handled in the source code of YATI (gdscript).
In the example the imported TeleporterEntry node would have an "exit" field in the metadata with the value 3. I don't see an obvious way to identify the TeleporterExit object among the imported nodes.
Describe the solution you'd like
An "id" field in the metadata would be needed in order to identify the linked node in post processing. I'm not sure if that feature should be guarded by an import option (just like the "Class" field).
Describe alternatives you've considered
N/A
Additional context
Very useful Godot plugin. Thanks!
Is your feature request related to a problem? Please describe.
In Tiled, you can make each tile only use a certain area of an image rather than using the whole image.
It looks like this in the Tiled UI
Which lets you draw a map like this
But when imported via YATI, it looks like this in Godot
Describe the solution you'd like
Use an atlas texture or similar in Godot to support this Tiled workflow
Describe alternatives you've considered
You could use some of the other styles of tilesets but this is good for using a single texture
Additional context
Describe the bug
Maps imported with YATI lack all collision data when exported to macOS using the macOS template in Godot 4.2
To Reproduce
Steps to reproduce the behavior:
Import a map from Tiled to Godot 4.2 with YATI
On a Mac running 13.5 load the project (we are working via multiple machines using GitHub with macOS and Windows)
Project->Export
Select the macOS export template
Fill out necessary info for project
Export Project
Expected behavior
The project runs in a similar fashion to Windows export with maps having all collision and visual data
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
We are developing on both Windows 10 and macOS 13.5
Tiled maps are being developed and imported on Windows 10
macOS export is being done on macOS 13.5
Additional context
Just looking for any feedback on possible resolution of things we may be doing incorrectly. If there are any external resource file extensions that need to be included in the Resource filters on the export options please let us know. Everything runs fantastic on windows. All animations and tiles are preset on Mac, the only thing lacking is the collision layer.
Thanks!
Describe the bug
In Tiled I can define a Tiled object that is of class instance
and has a res_path
that is of type File and points to a .tscn
. Tiled will save the file path as a relative path from where the Tiled object is defined. If I save this Tiled object as a template .tx
file and place the template in a different folder to the tilemap, then the res_path
relative path will be pointing to the .tscn
file from within the template directory .tx
. This means that the instancing of the scene will fail because the importer expects the scene res_path
to be relative to the map .tmx
file.
Standard Example:
/maps/map1.tmx
/scenes/object.tscn
In map1.tmx
I add an object layer with a point object of class instance
and res_path = "../scenes/object.tscn"
If I then save that point object as a template:
/maps/templates/objtemplate.tx
then tiled makes res_path = "../../scenes/object.tscn
and YATI will try to load this res-path from the /maps
directory which is where the map1.tmx
is being created. This will cause a scene import error because res_path is going up 2 directories now.
To Reproduce
Steps to reproduce the behavior:
class=instance
and setting custom File property res_path
pointing to a godot .tscn
filetemplates/
.tscn
file.Expected behavior
The issue is the res_path being used to load the .tscn:
# approx - line 676 in TilemapCreator.gd
var scene = load_resource_from_file(res_path)
YATI should adjust the res_path to be relative to the template.tx folder rather than the tilemap.tmx file when the object being instantiated is defined from within a template.
Examle map (zipped)
A zip file containing a small but complete example to reproduce the issue.
This could accelerate resolving it.
Working fix / hack
This is inside TilemapCreator.gd
at about line 647 onwards. See the added #
comments with the proposed fix.
if obj.has("template"):
var template_path = _base_path.path_join(obj["template"])
var template_dict = preload("DictionaryBuilder.gd").new().get_dictionary(template_path)
var template_tileset = null
if template_dict.has("tilesets"):
var tilesets = template_dict["tilesets"]
var tileset_creator = preload("TilesetCreator.gd").new()
tileset_creator.set_base_path(template_path)
tileset_creator.set_map_parameters(Vector2i(_map_tile_width, _map_tile_height))
if _map_wangset_to_terrain:
tileset_creator.map_wangset_to_terrain()
template_tileset = tileset_creator.create_from_dictionary_array(tilesets)
if template_dict.has("objects"):
for template_obj in template_dict["objects"]:
# FIX begin
# since we are loading this object from a template file, save the template file's
# directory path as additional data on the template_obj so that if the template
# makes use of custom properties of type File, then the file paths can be computed correclty
# since they would be relative to the folder containing the template .tx file
template_obj["template_dir_path"] = template_path.get_base_dir()
handle_object(template_obj, layer_node, template_tileset, Vector2(obj_x, obj_y))
# v1.2: New class 'instance'
if godot_type == _godot_type.INSTANCE and not obj.has("template") and not obj.has("text"):
var res_path = get_property(obj, "res_path", "file")
if res_path == "":
printerr("Object of class 'instance': Mandatory file property 'res_path' not found or invalid. -> Skipped")
_error_count += 1
else:
if obj.has("template_dir_path"):
# FIX Continued...
# when the INSTANCE is from a template, then res_path will be the relative path to the .tscn file
# from the folder containing the template.tx file
# hence, res_path should be template_dir_path + res_path
res_path = obj.template_dir_path.path_join(res_path)
var scene = load_resource_from_file(res_path)
Will try and create a minimal project to test this
Describe the bug
I have a Map with tilesets with different tilesizes (16x16 and 64x64)
this won't import correctly
Describe the bug
When using isometric tiles that are a different size from the grid tile (e.g. double height tiles for trees as pictured in example below)
version 1.1.2 would import the tiles with expected alignment (matching how Tiled interprets them when painting to a map)
In version 1.2.0 (and onwards) tiled imports the tileset assuming the boundary for where to place the tile is centered
This results in tiles being painted half a tile lower than expected as depicted below
Additionally, their collision physics are now completely distorted, see below for comparison:
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Tileset should import as expected, like it used to.
Desktop (please complete the following information):
Example map (zipped)
tempfarm.zip
Additional context
Add any other context about the problem here.
Describe the bug
i have one tileset and the collision layers are separated in two. ground and bridge.
i added a custom property physics layer with value 0 for ground, and physics layer 1 for bridge on thier each collision rectangle.
when imported all collision are just set to physics layer 0
im not sure if its a bug or not implemented yet. but ive seen on the document on base tile there's a property physics_layer with int type. and these are the desired result when imported.
Desktop (please complete the following information):
Describe the bug
I'm trying to setup a Tile with two different collision rectangles. One is on the physics_layer
0, the other should be on the physics_layer
1 (which has different collisions layer, etc).
When importing my map, only the first rectangle (physics_layer = 0
) shows up. An error is raised in the console output :
scene/resources/tile_set.cpp:5431 - Index p_polygon_index = 1 is out of bounds (physics[p_layer_id].polygons.size() = 1).
The map is still imported, but there is no collision rectangle for the physics_layer 1
To Reproduce
physics_layer
and setting it to 1. This rectangle should be imported as a collision rectangle for physics_layer 1scene/resources/tile_set.cpp:5431 - Index p_polygon_index = 1 is out of bounds (physics[p_layer_id].polygons.size() = 1).
Expected behavior
The collision rectangle/polygon should be imported on physics_layer 1 for that tile.
Screenshots
Screenshots of the Tiled setup :
Screenshot of the resulting import in Godot :
Desktop
Example map (zipped)
Here's a small example.
Is your feature request related to a problem? Please describe.
I'm using NormalMaps in my level in order to simply achieve some beautiful lighting effects. Unfortunately, I found no way to do that using YATI.
Describe the solution you'd like
It could maybe be added as a file CustomProperty of the tileset in Tiled? Or independently for each tile when using separate tiles pictures?
Describe alternatives you've considered
For now I need to manually modify the node generated by YATI, changing the TileSet Texture (CanvasTexture) and manually adding the TileMap Texture parameter. Unfortunately I need to redo this each time I make a change in my Tiled level.
Additional context
Thanks for making YATI, that's a brilliant plugin that I now can't live without. :]
Is your feature request related to a problem? Please describe.
In Tiled you can define template objects, where each template object may have zero or more properties.
When you make an instance of an object from a template, Tiled makes the template properties available in the object instance so that the property values can stay as they are defined in the template or be overridden in the instanced version. Moreover, you can define additional properties that are not part of the template.
In YATI, at the moment, when we instance a template we have the obj
that uses the template, the template is loaded and then an instance of the object is created in the godot layer from the template. However, any property overrides / additions defined in obj are not carried over into the template, and hence are not available.
Describe the solution you'd like
Merge and override any property changes from the obj
into the template_obj
before instancing.
Working solution
# add the following code just before handling the creation of the object from template
# this code is approximately lines 663 in TilemapCreator.gd
# override and merge properties defined in obj with properties defined in template
# since obj may override and define additional properties to those defined in template
if obj.has("properties"):
if not template_obj.has("properties"):
# template comes without properties, since obj has properties
# then merge them into the template
template_obj["properties"] = obj.properties
else:
# merge obj properties that may have been overridden in the obj instance
# and add any additional properties defined in instanced obj that are
# not defined in template
for prop in obj["properties"]:
var found = false
for templ_prop in template_obj["properties"]:
if prop.name == templ_prop.name:
templ_prop.value = prop.value
found = true
break
if not found:
template_obj["properties"].append(prop)
handle_object(template_obj, layer_node, template_tileset, Vector2(obj_x, obj_y))
Describe the bug
Unable to import a simple tiled map.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Map is opened or a scene is created.
Actual behavior
The tmx map shows up, and sometimes an incomplete scene shows up. The incomplete scene doesn't render the tiles at all. The following output is shown:
importing
Import file 'res://asset/maps/dev/test.tmx'
ERROR: Image file '../Tiles/building_center_N.png' not found.
res://addons/YATI/TilesetCreator.gd:274 - Attempt to call function 'get_width' in base 'null instance' on a null instance.
Import finished with 1 error.
opening
No loader found for resource: res://.godot/imported/test.tmx-c64eac05962bf4aafb175d31b1bd83da.tscn.
Failed loading resource: res://asset/maps/dev/test.tmx. Make sure resources have been imported by opening the project in the editor at least once.
editor/editor_node.cpp:1270 - Condition "!res.is_valid()" is true. Returning: ERR_CANT_OPEN
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Examle map (zipped)
example.zip
Additional context
Add any other context about the problem here.
This may be partially a nuance of how custom tile data is implemented in Godot, but I think there is room for some documentation improvements here.
The custom data on the tile is an array of values, which at first made me think there was a bug in the importer for not keeping the key name. I later realized that the custom data keys/types are stored on the tileset themselves.
This is fine that its implemented this way, but can be confusing for a newer user, especially because it combines them from all tiles (meaning the index is global, not the same as the order in Tiled)
The other part that is slightly confusing is the Tiled tileset is where the custom tile data gets stored (where everything else in this plugin is seemingly stored in the map files). This file does not appear in the godot FileSystem dock (when saved there), which may cause confusion about needing the file, embedding it in the map file, etc.
Documentation improvements to help understand:
Describe the bug
The folder structure with both the GDScript an CSharp versions in separate subfolders does not work well with the expected structure from godot. To actually use the addon, the user has to move the addon path.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
It should just work out of the box.
Proposed Solution
Either just explain this in the description on the asset lib so that users know this, or adjust the folder structure to work out of the box.
I think the easiest would be to split this into two addons:
addons/
YATI_gdscript/
plugin.cfg (name: YATI GDScript)
...other files
YATI_csharp/
plugin.cfg (name: YATI CSharp)
...other files
This way users can easily download and enable the version they want to have.
Describe the bug
Wang Tilesets are not correctly imported, the importer only supports one color for terrains and wangs.
Not all Tiled Terrains are available in Godot with this import routine
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Import all the colors used in the tileset and create all the terrain options needed to use
Additional context
i had this working in my discontinued tiled importer, trying to get this working in yati
Describe the bug
godot_node_type
and/or res_path
are not loaded from property types file, as a result, any objects with the relevant properties set, do not get instanced:
To Reproduce
Steps to reproduce the behavior:
res_path
and godot_node_type='instance'
properties.class
property set to above class.To work around
Double-click the res_path
and godot_node_type
for every object in the map, change them to non-default values, then change them to their default values, so they become un-greyed.
Expected behavior
Objects with godot_node_type='instance'
and res_path
set to a .tscn
file should be instanced in-game.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Examle map (zipped)
A zip file containing a small but complete example to reproduce the issue.
This could accelerate resolving it.
Additional context
Add any other context about the problem here.
Hello! Sorry, it might not be a bug but I'm not sure if I'm doing something wrong here.
Describe the bug
I try to create collisions in tiled but they won't appear in the tileset setting in Godot. I've managed to create physics layers in the tilemap but when I'm creating the collision shapes inside tiled and save the file, they are not being updated in Godot.
All other properties update correctly.
To Reproduce
Create collision shape for tile in Tiled and add the custom property physics_layer to it.
Go back to godot
Check the tileset
the tile does not have the collision polygon set to it.
Expected behavior
Collision polygon in Godot should be created and be the same as the one in Tiled
Desktop:
Is your feature request related to a problem? Please describe.
This request points to this thing mentioned in the readme:
Tileset animation in Godot requires involved tiles being equidistant and either horizontally or vertically arranged.
In Tiled you can randomly choose every frame tile, such animations won't map and are skipped.
Describe the solution you'd like
in my importer i found a solution for this:
https://github.com/feendrache/Godot4-TiledImporter
in https://github.com/feendrache/Godot4-TiledImporter/blob/main/naddys_tiled_maps/tileset_creator.gd
around line 143 i made a function to get the tiles used by the animation
Additional context
I created my importer due to need and would stop working on it, redirecting the people to you if this would be ok
Describe the bug
Error message in the title prints to Godot output console whenever my map is reimported. At first I thought this was due to my png being in a different directory than all my tiled files but I am still getting this when I redo this with everything in one directory. My map seems to be importing just fine but it's not clear what's going wrong and if there is a failure somewhere else in the process I just haven't seen yet.
To Reproduce
Expected behavior
No error message.
Desktop (please complete the following information):
Examle map (zipped)
project.zip
Is your feature request related to a problem? Please describe.
It is possible using the core features in this codebase to load Tiled maps at runtime and not just in-editor. This provides a lot of value.
Describe the solution you'd like
I have achieved this feature by taking the code from this repository, removing the requirement of Godot editor, and simply returning a Node2D without saving to resources. Given a clean refactor, this functionality could be extended to both runtime loading and editor. It should be noted that I wrote the alternate runtime version in C#.
Describe alternatives you've considered
If runtime loading is not supported, I will continue having a fork and adapt it to your repository's future changes. However I would rather give back to the community and reference this repo directory.
Additional context
Let me know if you need access to the c# runtime version.
Describe the bug
While the reference doc is unclear as to naming convention, the code suggests that setting custom property collision_layer
on a tileset will result in the parsing of that property value to be set as a collision layer(s). I have a tileset with this custom property set, shown below in-app and in the .tsx
file:
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.10" tiledversion="1.10.0" name="testset" tilewidth="32" tileheight="32" tilecount="8" columns="2">
<properties>
<property name="collision_layer" value="4,5"/>
</properties>
Looking at the code here it seems this is the expected behavior. However, the resulting .tscn
file doesn't end up with the correct collision layer. Instead, it has the default collision layer 1 and metadata called "collision layer" set to the value I specified.
[sub_resource type="TileSet" id="TileSet_ypy1m"]
tile_shape = 1
tile_layout = 5
tile_size = Vector2i(32, 16)
physics_layer_0/collision_layer = 1
sources/0 = SubResource("TileSetAtlasSource_ltbpe")
metadata/collision_layer = "4,5"
Clearly my value is being found but it is not managing to trigger as a well-known value, instead being added to generic metadata.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The appropriate physics layers should be set as outlined
Desktop (please complete the following information):
Simply put, since Godot 4.2, TileMap.CellQuadrantSize
was renamed to TileMap.RenderingQuadrantSize
. Thus it breaks on build when adding this plugin to a 4.2 project.
Could there be a 4.2 branch for this, please?
Describe the bug
When adding a new layer or changing a collision polygon, the map fails to import.
Godot must be restarted to see changes.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
That the file should have it's cache cleared and re-imported
Screenshots
...
Desktop (please complete the following information):
Describe the bug
When setting a post processor C# script I get the following error:
Postprocessing was skipped due to some error.
Script error (Class name not equal filename? Or not inherited from Node?). -> Postprocessing skipped
However if you check the Zip you can see that the class name and file name are the same and it inherits from node, has the correct method name, and the correct parameters.
To Reproduce
Expected behavior
Post processor runs? :D
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Examle map (zipped)
This includes the map, tileset, and my post processor file
MapReproduce.zip
Describe the bug
I made a map in Tiled, but the Godot map is not the same, some props are missing and some animations too.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The map should've been imported as in Tiled.
Screenshots
Missing Atlas for props (even though it is in my Godot directory)
Desktop (please complete the following information):
Describe the bug
When refocusing on Godot to let the addon reimport changes, and multiple tmx files have had changes, hundreds of thousands of errors repeat themselves in the Godot console. The easiest error message to reproduce is This function in this node (Tile Layer 1) can only be accessed from either the main thread or a thread group. Use call_deferred() instead.
but I have seen others. It's also very easy for me generate exactly 1280 errors (not including errors from #30).
Following these errors, Import succeeded.
is printed to the console, but opening the imported tmx file in the scene editor shows this is not the case.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
No error messages. successful import.
Desktop (please complete the following information):
Examle map (zipped)
Same zip in #30
Hello there, I am contacting you because I am having trouble getting the plugin installed correctly into Godot 4.1.2. Myself and another collaborator have attempted but seem to be unable to get the plugin functioning like intended. We have followed you instructions and also searched for solutions online. i hate to ask, but you provide a simple step by step explanation of how to correctly install the plugin and what save format we should use to make sure all of our tilesets and tilemaps transfer into Godot? I really appreciate the help. thanks
Mythgard Studios
Hi,
thanks a lot for this really powerfull addon.
i meet an issue. i coded a AI movement for NPC via AstarGrid2D algo.
All works fine with a tilemap made in Godot 4.But it does not work with a tilemap made in Tiled then imorted via YATI.
Node is found but i think get_cell_tile_data function does not find custom data layer "walkable" (Tileset property)
Any idea plz?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.