Skip to content

Instantly share code, notes, and snippets.

@cgbeutler
Last active March 25, 2022 01:55
Show Gist options
  • Save cgbeutler/0c78e1581dad5e109d32f374ecae6b10 to your computer and use it in GitHub Desktop.
Save cgbeutler/0c78e1581dad5e109d32f374ecae6b10 to your computer and use it in GitHub Desktop.
Quick Exporter for Aseprite that uses layer names to be smarter
----------------------------------------------------------------------
-- Author: Cory Beutler
-- License: MIT (So you can't sue me... Otherwise go wild!)
--
-- Exports the current file using layer name prefixes to be smart.
-- The png and json files are always exported with all their data.
-- Texture png files will be auto-named <filename>.png
-- Json files will be auto-named <filename>.asejson
-- Layer name prefixes it recognizes:
-- _ Hide from all exports. Useful for guide and reference layers.
-- > An extra export will be performed on this layer. This can be
-- placed on as many groups/layers as you want. Each will be
-- exported to its own files auto_named with suffixes based on
-- their group/layer path like so: <filename>[_<group>]_<layer>
-- Feel free to change the settings in 'export_current' below to match
-- your needs. It will affect ALL exports using this script.
-- Installing:
-- Easiest way is to zip it up and rename
-- from `.zip` to `.aseprite-extension`, then double click it. This
-- will trigger aseprite to launch and install.
----------------------------------------------------------------------
-- Utility Funcs --
local function starts_with(str, start)
return str:sub(1, #start) == start
end
local function ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
local function trim_prefix(str, prefix)
return (str:gsub( "^" .. prefix, ""))
end
local function trim_suffix(str, suffix)
return (str:gsub( suffix .. "$", ""))
end
function init( plugin )
if app.apiVersion == nil or app.apiVersion < 15 then
app.alert("Plugin Minimum Requirement not met: Aseprite v1.2.30 or greater")
return
end
plugin:newCommand{
id = "monster-vial-com-godot-exporter",
title = "Export for Godot",
group = "file_save",
onclick = godot_export
}
end
function exit( plugin )
end
----
-- Save layer visibility and set based on name
-- input:
-- layers - aseprite layers array like from a sprite
-- output:
-- list of bools and lists representing all starting visibility values
----
function __push_visibility( layers )
local saved_visibility = {}
for i,layer in ipairs( layers ) do
if starts_with( layer.name, "_" ) then
table.insert(saved_visibility, i, layer.isVisible)
layer.isVisible = false
elseif layer.isGroup then
table.insert(saved_visibility, i, __push_visibility( layer.layers ))
else
table.insert(saved_visibility, i, layer.isVisible)
layer.isVisible = true
end
end
return saved_visibility
end
----
-- Restore visibility
-- input:
-- layers - aseprite layers array like from a sprite
-- saved_visibility - the saved visibility results returned from __push_visibility
-- output:
-- void
----
function __restore_visibility( layers, saved_visibility )
for i,layer in ipairs( layers ) do
if starts_with( layer.name, "_" ) then
layer.isVisible = saved_visibility[i]
elseif layer.isGroup then
__restore_visibility( layer.layers, saved_visibility[i] )
else
layer.isVisible = saved_visibility[i]
end
end
end
----
-- Export with settings best for godot.
-- input:
-- layer - optional. If provided, will export that layer to a file with [_group]_layer suffix
----
function __export_current( basename, layer )
local layerSuffix = ""
local askOverwrite = true
if layer then
askOverwrite = false
-- sanitize the name and build suffix
layerSuffix = (layerSuffix:gsub( "/", "_"))
layerSuffix = (layerSuffix:gsub( "\\", "_"))
layerSuffix = trim_prefix(layerSuffix, "_")
layerSuffix = trim_prefix(layer, ">")
layerSuffix = "_" .. layerSuffix
end
-- Currently, Aseprite doesn't translate slices for the extrude key, so we can't use it.
if #app.activeSprite.slices > 0 then
app.command.ExportSpriteSheet {
ui=false,
askOverwrite=askOverwrite,
type=SpriteSheetType.PACKED,
columns=0, rows=0,
width=0, height=0,
bestFit=true,
-- texture: '<basename>_<group>_<layer>.png'
textureFilename=basename .. layerSuffix .. ".png",
-- data: '<basename>_<group>_<layer>.asejson'
dataFilename=basename .. layerSuffix .. ".asejson",
dataFormat=SpriteSheetDataFormat.JSON_HASH,
borderPadding=0,
shapePadding=0,
innerPadding=0,
trim=false,
extrude=false,
openGenerated=false,
layer=layer,
tag="",
splitLayers=false,
listLayers=false,
listTags=true,
listSlices=true
}
elseif #app.activeSprite.tags > 0 or #app.activeSprite.frames > 1 then
app.command.ExportSpriteSheet {
ui=false,
askOverwrite=askOverwrite,
type=SpriteSheetType.PACKED,
columns=0, rows=0,
width=0, height=0,
bestFit=true,
-- texture: '<basename>_<group>_<layer>.png'
textureFilename=basename .. layerSuffix .. ".png",
-- data: '<basename>_<group>_<layer>.asejson'
dataFilename=basename .. layerSuffix .. ".asejson",
dataFormat=SpriteSheetDataFormat.JSON_HASH,
borderPadding=0,
shapePadding=0,
innerPadding=1,
trim=false,
extrude=true,
openGenerated=false,
layer=layer,
tag="",
splitLayers=false,
listLayers=false,
listTags=(#app.activeSprite.tags > 0),
listSlices=false
}
else
-- No frames, animations, or slices. Just one static image.
app.command.ExportSpriteSheet {
ui=false,
askOverwrite=askOverwrite,
type=SpriteSheetType.HORIZONTAL,
columns=0, rows=0,
width=0, height=0,
bestFit=false,
-- texture: '<basename>_<group>_<layer>.png'
textureFilename=basename .. layerSuffix .. ".png",
-- data: skipped
dataFilename="",
dataFormat=SpriteSheetDataFormat.JSON_HASH,
borderPadding=0,
shapePadding=0,
innerPadding=0,
trim=false,
extrude=false,
openGenerated=false,
layer=layer,
tag="",
splitLayers=false,
listLayers=false,
listTags=false,
listSlices=false
}
end
end
----
-- Scan layer names and do extra exports for '>' prefixed layers
-- input:
-- layer - optional. If provided, will export that layer to a file with [_group]_layer suffix
----
function __export_prefixed_layers( basename, layers, layer_path )
layer_path = layer_path or ""
for i,layer in ipairs( layers ) do
if starts_with( layer.name, ">" ) then
__export_current( basename, layer_path .. layer.name )
end
if layer.isGroup then
__export_prefixed_layers( basename, layer.layers, layer_path .. layer.name )
end
end
end
function godot_export()
local sprite = app.activeSprite
if not sprite then
app.alert("There is no sprite to export")
return
end
local basename = sprite.filename
if not basename then
app.alert("Sprite is missing filename. Please save first.")
return
end
-- Trim off the sprite's suffix --
if ends_with( basename, ".ase") then
basename = trim_suffix(basename, ".ase")
elseif ends_with( basename, ".aseprite") then
basename = trim_suffix(basename, ".aseprite")
else
app.alert("Unrecognized extension for this sprite file. Expected '.ase' or '.aseprite'")
return
end
local saved_visibility = __push_visibility( sprite.layers )
__export_current( basename )
__export_prefixed_layers( basename, sprite.layers )
__restore_visibility( sprite.layers, saved_visibility )
app.refresh()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment