Last active
March 25, 2022 01:55
-
-
Save cgbeutler/0c78e1581dad5e109d32f374ecae6b10 to your computer and use it in GitHub Desktop.
Quick Exporter for Aseprite that uses layer names to be smarter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---------------------------------------------------------------------- | |
-- 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