Hi there!
Here is my code example for creating a mesh from a tilemap in runtime:
An example is well commented, hope it helps someone to open the wonderful world of Defold meshes
Try it here: HTML 5 demo
How to use:
- Copy ‘mtool.lua’ module to your project.
- Create a standard tilemap.
- Add to scene a game object with a mesh component. We will use it as target later.
- In your code require mtool:
local mtool = require "src.mtool"
- Fill the options table:
local options = {
tilemap = "level#level", -- Tilemap URL.
layer = "layer1", -- Tilemap layer name.
w = 16, -- Horizontal number of tiles in tileset (texture atlas).
h = 16, -- Vertical number of tiles in tileset (texture atlas).
tilesize = 16, -- Size of tile in pixels (it will be use as scale factor when a script generates quads).
-- Note: The same image that using as tilesource image we are using as a texture for generated mesh.
-- Each tile in tilemap layer will represented as box.
--
-- Each box contains 6 edges (faces). We can replacement their textures by setting tile number for each edge.
-- '1' is front edge, '2' - top, etc.
-- [2]
-- [4][1][5][6]
-- [3]
-- For example we want see a mixed grass tile (N) on front edge and pure green tile (M) on top edge.
-- So, mapping it as: [N] = {N, M, N, N, N, N}
--
tile_info = {
[2] = {2, 18, 34, 1, 1, 1},
[3] = {3, 19, 35, 1, 1, 1},
[4] = {4, 20, 36, 1, 1, 1},
[6] = {6, 19, 35, 1, 1, 1},
[51] = {51, 49, 49, 49, 49, 49},
[53] = {53, 49, 49, 49, 49, 49},
},
-- You also can setup function 'tile_info_fn' for dynamic setting tile number. It may useful for generating levels in runtime.
-- tile_info_fn = function(tileno, x, y)
-- if tileno == 1 then return {1, 4, 1, 1, 1, 1} end
-- end
optimize = false, -- If 'true' a script will culling the hidden by neighbors faces (edges 2,3,4,5).
optimize_back = false -- If 'true' a script will culling back face (6) for all tiles.
-- Also you may setup a texture atlas and setup for some tile numbers UV coordinates directly way.
-- It's optionaly and made for further commits.
-- All units are in pixels. Top-left corner is 0,0.
-- For example:
-- texture = {
-- width = 512,
-- height = 512,
-- [2] = {x = 128, y = 0, w = 128, h = 256},
-- }
}
- Create a mesh from tilemap:
self.grid = mtool.create_mesh_from_tilemap("go#mesh", options)
- Hide origin tilemap.
msg.post(options.tilemap, "disable")
An example contains utility camera contoller script and uses rendercam extension.
Custom render script is modified rendercam render script where fixed render ordering 3d models and 2d objects. In example you may see that sprites are drawing in the same space as mesh tilemap and their can overlap each other.
If you do not need to see light source and want to do flat colors then remove “Diffuse light calculations” sections in the mesh fragment shader (assets/material/mesh.fp). In this case it should looks like
void main()
{
// Pre-multiply alpha since all runtime textures already are
vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
vec4 color = texture2D(tex0, var_texcoord0.xy)*tint_pm;
gl_FragColor = vec4(color.rgb*var_color0.rgb, color.a*var_color0.a);
}
Happy Defolding!