- Modifié
Skin PlaceHolder and Export Layer Script
Hi Everyone,
The Script for export layers from PS, and import them to Spine is pretty good! This is really usefull and it saves a lot of time!
Thanks for this script!
But I have a question for the skin placeholder.
The .json data imported do not create a skin placeholder for the layer.
And we have to recompose all layers with the skin placeholder for customisation.
I mean, if I have for example 2 folders, one for a Spine boy Blue, one for a Spine Boy Red...
There is a way to save time for this? or it is possible that spine recognize the different folder for the skin placeholder/customization and update the layers with the good path?
As we have many differents...something like 40 elements, it will be long to redrag and drop for each customisation.
Thank you.
Have a good day.
Maybe groups in Photoshop could be used to define if an attachment should be placed on a skin placeholder in the json it exports. Would that be sufficient ?
Unfortunetely, I don't know very well.
In fact I'm not a dev, and I don't have any notion in code.
If the json exported from photoshop can take into account the group, I think it will be great.
We will save some times to recreate the organization in Spine.
Don't have it working yet and I've had to take a break from the computer, but I'll get back to it later
Thank you Shiu for your answer!
I've added skin exporting to the script and you can get it here http://esotericsoftware.com/files/LayersToPNG.zip
I've done a bit of testing, but there might be corner cases that I haven't covered which will make it bug out. You can't have groups within groups, might add that functionality later.
Unfortunately it seems that to be able to support skins properly in the script, a major part of it will need to be rewritten. The problem is defining which slots the skins should go into, might be a way around it but so far I've not had any luck with it.
Managed to make it work but it's not perfect.
You will need to create layers for each slot you want, these layers should be on the Document layer (Not in any groups). Layers inside groups should use the same names as those base layers.
Here's an example.
Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même
I've just created som black boxes in the bottom right corner for the base layer so they are easy to select in Spine and delete if you don't want them
Note the above is no longer needed Nate did some magic and it now creates slots automatically by comparing layer names. If the name of a layer inside of a group only exists once it will create a slot for it.
I hope it helps even if it isn't perfect.
Thank you so much Shiu!
It's really good! It' s sufficient enough, it helps perfectly.
Thanks for your time.
Glad it's useful Nate tweaked the script a bit so if you download the new one it will be a bit easier to use.
- Modifié
Hello.. Sorry I'd replied to this before and edited a couple of times before deleting and starting again.
I'm using Spine 1.9.01 pro.
The current / newest (or the old one for that matter) script doesn't produce valid json. There are commas after the last entry in the arrays / collections. Not that it matters THAT much because the old version of the script did the same thing and Spine was able to import it ok. It's just easier if it's valid to load it into a json editor and see what's going on.
I have no problem importing the output from the old script (albeit without skins), but the newest script produces the error "An error occurred while importing the skeleton...".
Any ideas what's going on?
TC
EDIT!!!
Ok.. I've had a look at the json from the new script and it would seem as if either the "slotName" or "attachmentName" is missing from the skin definition.
Here's the output from the new script:
"skins": {
"default": {
"head": {
"x": 258.5,
"y": 361,
"width": 94,
"height": 85
},
...
and heres the output from the old script:
"skins": {
"default": {
"head": {
"head": {
"x": 258.5,
"y": 361,
"width": 94,
"height": 85
}
},
...
I edited the new script output json to the correct format and it now imports ok.
The offending line(s) in the new script are:
if (attachmentName == placeholderName) {
json += "\t\t\"" + placeholderName + "\":{\"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "},\n";
} else {
json += "\t\t\"" + placeholderName + "\":{\"name\":\"" + attachmentName + "\", \"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "},\n";
}
The line in the old script was:
json += "\"" + trim(layer.name) + "\":{\"" + trim(layer.name) + "\":{\"x\":" + x + ",\"y\":" + y+ ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}},\n";
And the lines I fixed are now:
if (attachmentName == placeholderName) {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}},\n";
} else {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"name\":\"" + attachmentName + "\", \"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}},\n";
}
I don't know whether I've missed the intention of the new script, but Spine didn't want to import the output of that script without the slotName - attachmentName json being correct.
Cheers,
TC
That's strange. I'll fix it today.
Hi.. cheers for that.. I've updated my post above.
TC
Here's my fixed version of the script. The json should be well formed and the slotName / attachmentName is fixed.
(It might be useful to you / anyone.. I don't know if it's quite right though, so you might want to sanity check it first )
Cheers.
// This script exports photoshop layers as individual images.
// It also write a JSON file that can be imported into Spine
// where the images will be displayed in the same positions.
// Settings.
var ignoreHiddenLayers = true;
var saveTemplate = false;
var savePNGs = true;
var saveJSON = true;
var saveSkins = false;
var scaleFactor = 0.5;
showDialog();
function main () {
// Output dir.
var dir = app.activeDocument.path + "/images/";
new Folder(dir).create();
var name = decodeURI(app.activeDocument.name);
name = name.substring(0, name.indexOf("."));
app.activeDocument.duplicate();
if (saveTemplate) {
if (scaleFactor != 1) scaleImage();
var file = new File(dir + "/template");
if (file.exists) file.remove();
activeDocument.saveAs(file, new PNGSaveOptions(), true, Extension.LOWERCASE);
if (scaleFactor != 1) stepHistoryBack();
}
// Collect original layer visibility and hide all layers.
var layers = [];
var layerParents = [];
getLayers(app.activeDocument, layers);
var layerCount = layers.length;
var layerVisibility = {};
//Sort the layers so skin keys don't show multiple times.
layers.sort(function (a, b) {
if (a.parent.name < b.parent.name) return -1;
if (a.parent.name > b.parent.name) return 1;
});
for (var i = layerCount - 1; i >= 0; i
---
) {
var layer = layers[i];
layerVisibility[layer] = layer.visible;
layer.visible = false;
}
// Save JSON.
if (saveJSON || savePNGs) {
var skins = {}, slots = {};
for (var i = layerCount - 1; i >= 0; i
---
) {
var layer = layers[i];
if (ignoreHiddenLayers && !layerVisibility[layer]) continue;
var skinName = (saveSkins && layer.parent.typename == "LayerSet") ? trim(layer.parent.name) : "default";
var skinLayers = skins[skinName];
if (!skinLayers) skins[skinName] = skinLayers = [];
skinLayers[skinLayers.length] = layer;
slots[trim(layer.name)] = true;
}
var json = "{\"bones\":[{\"name\":\"root\"}],\n\"slots\":[\n";
var numSlots = sizeAssocArray(slots);
var curSlot = 0;
for (var slotName in slots) {
if (!slots.hasOwnProperty(slotName)) continue;
json += "\t{\"name\":\"" + slotName + "\",\"bone\":\"root\",\"attachment\":\"" + slotName + "\"}";
curSlot++;
//omit final comma for well formed json
if(curSlot < numSlots) {
json += ",\n";
} else {
json += "\n";
}
}
json += "],\n\"skins\":{\n";
var numSkins = sizeAssocArray(skins);
var curSkin = 0;
for (var skinName in skins) {
if (!skins.hasOwnProperty(skinName)) continue;
json += "\t\"" + skinName + "\":{\n";
var skinLayers = skins[skinName];
var numSkinLayers = skinLayers.length;
var curSkinLayer = 0;
for (var i = skinLayers.length - 1; i >= 0; i
---
) {
var layer = skinLayers[i];
var placeholderName = trim(layer.name);
var attachmentName = skinName == "default" ? placeholderName : skinName + "/" + placeholderName;
var x = app.activeDocument.width.as("px") * scaleFactor;
var y = app.activeDocument.height.as("px") * scaleFactor;
layer.visible = true;
if (!layer.isBackgroundLayer)
app.activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false);
x -= app.activeDocument.width.as("px") * scaleFactor;
y -= app.activeDocument.height.as("px") * scaleFactor;
if (!layer.isBackgroundLayer)
app.activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true);
var width = app.activeDocument.width.as("px") * scaleFactor;
var height = app.activeDocument.height.as("px") * scaleFactor;
// Save image.
if (savePNGs) {
if (scaleFactor != 1) scaleImage();
if (skinName != "default") {
var path = new Folder(dir + "/" + skinName);
if (!path.exists) path.create();
}
var file = new File(dir + "/" + attachmentName);
if (file.exists) file.remove();
activeDocument.saveAs(file, new PNGSaveOptions(), true, Extension.LOWERCASE);
if (scaleFactor != 1) stepHistoryBack();
}
if (!layer.isBackgroundLayer) {
stepHistoryBack();
stepHistoryBack();
}
layer.visible = false;
x += Math.round(width) / 2;
y += Math.round(height) / 2;
if (attachmentName == placeholderName) {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}}";
} else {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"name\":\"" + attachmentName + "\", \"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}}";
}
//omit final comma for well formed json
curSkinLayer++;
if(curSkinLayer < numSkinLayers) {
json += ",\n";
} else {
json += "\n";
}
}
json += "\t\}";
//omit final comma for well formed json
curSkin++;
if(curSkin < numSkins) {
json += ",\n";
} else {
json += "\n";
}
}
json += "},\n\"animations\": { \"animation\": {} }}";
if (saveJSON) {
// Write file.
var file = new File(dir + name + ".json");
file.remove();
file.open("w", "TEXT");
file.lineFeed = "\n";
file.write(json);
file.close();
}
}
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
// Unfinished!
function hasLayerSets (layerset) {
layerset = layerset.layerSets;
for (var i = 0; i < layerset.length; i++)
if (layerset[i].layerSets.length > 0) hasLayerSets(layerset[i]);
}
function scaleImage() {
var imageSize = app.activeDocument.width.as("px");
app.activeDocument.resizeImage(UnitValue(imageSize * scaleFactor, "px"), undefined, 72, ResampleMethod.BICUBICSHARPER);
}
function stepHistoryBack () {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( "HstS" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Prvs" ));
desc.putReference(charIDToTypeID( "null" ), ref);
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
}
function getLayers (layer, collect) {
if (!layer.layers || layer.layers.length == 0) return layer;
for (var i = 0, n = layer.layers.length; i < n; i++) {
// For checking if its an adjustment layer, but it also excludes
// LayerSets so we need to find the different types needed.
//if (layer.layers[i].kind == LayerKind.NORMAL) {
var child = getLayers(layer.layers[i], collect)
if (child) collect.push(child);
//}
}
}
function trim (value) {
return value.replace(/^\s+|\s+$/g, "");
}
function hasFilePath() {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
return executeActionGet(ref).hasKey(stringIDToTypeID('fileReference'));
}
function showDialog () {
if (!hasFilePath()) {
alert("File path not found.\nYou need to save the document before continuing.");
return;
}
var dialog = new Window("dialog", "Export Layers");
dialog.savePNGs = dialog.add("checkbox", undefined, "Save PNGs");
dialog.savePNGs.value = savePNGs;
dialog.savePNGs.alignment = "left";
dialog.saveTemplate = dialog.add("checkbox", undefined, "Save template PNG");
dialog.saveTemplate.value = saveTemplate;
dialog.saveTemplate.alignment = "left";
dialog.saveJSON = dialog.add("checkbox", undefined, "Save JSON");
dialog.saveJSON.alignment = "left";
dialog.saveJSON.value = saveJSON;
dialog.ignoreHiddenLayers = dialog.add("checkbox", undefined, "Ignore hidden layers");
dialog.ignoreHiddenLayers.alignment = "left";
dialog.ignoreHiddenLayers.value = ignoreHiddenLayers;
dialog.saveSkins = dialog.add("checkbox", undefined, "Save skins");
dialog.saveSkins.alignment = "left";
dialog.saveSkins.value = saveSkins;
var scaleGroup = dialog.add("panel", [0, 0, 180, 50], "Image Scale");
var scaleText = scaleGroup.add("edittext", [10,10,40,30], scaleFactor * 100);
scaleGroup.add("statictext", [45, 12, 100, 20], "%");
var scaleSlider = scaleGroup.add("slider", [60, 10,165,20], scaleFactor * 100, 1, 100);
scaleText.onChanging = function() {
scaleSlider.value = scaleText.text;
if (scaleText.text < 1 || scaleText.text > 100) {
alert("Valid numbers are 1-100.");
scaleText.text = scaleFactor * 100;
scaleSlider.value = scaleFactor * 100;
}
};
scaleSlider.onChanging = function () { scaleText.text = Math.round(scaleSlider.value); };
var confirmGroup = dialog.add("group", [0, 0, 180, 50]);
var runButton = confirmGroup.add("button", [10, 10, 80, 35], "Ok");
var cancelButton = confirmGroup.add("button", [90, 10, 170, 35], "Cancel");
cancelButton.onClick = function () { this.parent.close(0); return; };
runButton.onClick = function () {
savePNGs = dialog.savePNGs.value;
saveTemplate = dialog.saveTemplate.value;
saveJSON = dialog.saveJSON.value;
dialog.ignoreHiddenLayers.value;
scaleFactor = scaleSlider.value / 100;
saveSkins = dialog.saveSkins.value;
main();
this.parent.close(0);
};
dialog.orientation = "column";
dialog.center();
dialog.show();
}
function sizeAssocArray(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
Thank you for the fix, it appears to be correct. I've replaced the zip with the working version and it will be included in the next update of Spine.
Hello again!
It still wasn't correct as the code:
layers.sort(function (a, b) {
if (a.parent.name < b.parent.name) return -1;
if (a.parent.name > b.parent.name) return 1;
});
was screwing up the draw order of the imported data. Why do the layers need sorted by name?
I found that commenting this out seemed to work (maybe the sort was required for an earlier version of the script? As removing this fixed the problem and didn't create any others). The imported data now looks exactly as it does in photoshop and the skins are working correctly.
Again, let me know if this incorrect.
The script I'm using now is:
// This script exports photoshop layers as individual images.
// It also write a JSON file that can be imported into Spine
// where the images will be displayed in the same positions.
// Settings.
var ignoreHiddenLayers = true;
var saveTemplate = true;
var savePNGs = true;
var saveJSON = true;
var saveSkins = true;
var scaleFactor = 0.5;
showDialog();
//main();
function main () {
// Output dir.
var dir = app.activeDocument.path + "/images/";
new Folder(dir).create();
var name = decodeURI(app.activeDocument.name);
name = name.substring(0, name.indexOf("."));
app.activeDocument.duplicate();
if (saveTemplate) {
if (scaleFactor != 1) scaleImage();
var file = new File(dir + "/template");
if (file.exists) file.remove();
activeDocument.saveAs(file, new PNGSaveOptions(), true, Extension.LOWERCASE);
if (scaleFactor != 1) stepHistoryBack();
}
// Collect original layer visibility and hide all layers.
var layers = [];
var layerParents = [];
getLayers(app.activeDocument, layers);
var layerCount = layers.length;
var layerVisibility = {};
//Sort the layers so skin keys don't show multiple times.
/*
layers.sort(function (a, b) {
if (a.parent.name < b.parent.name) return -1;
if (a.parent.name > b.parent.name) return 1;
});
*/
for (var i = layerCount - 1; i >= 0; i
---
) {
var layer = layers[i];
layerVisibility[layer] = layer.visible;
layer.visible = false;
}
// Save JSON.
if (saveJSON || savePNGs) {
var skins = {}, slots = {}, newslots = new Array();
for (var i = layerCount - 1; i >= 0; i
---
) {
//getlayer
var layer = layers[i];
//do we want to use this layer?
if (ignoreHiddenLayers && !layerVisibility[layer]) continue;
//is the layer in a group? if so get the skin name, otherwise default skin
var skinName = (saveSkins && layer.parent.typename == "LayerSet") ? trim(layer.parent.name) : "default";
//does this skin already exist? if not create and clear new skin
var skinLayers = skins[skinName];
if (!skinLayers) skins[skinName] = skinLayers = [];
//store layer in skin
skinLayers[skinLayers.length] = layer;
var slotname = trim(layer.name);
slots[slotname] = true;
}
var json = "{\"bones\":[{\"name\":\"root\"}],\n\"slots\":[\n";
var numSlots = sizeAssocArray(slots);
var curSlot = 0;
for (var slotName in slots) {
if (!slots.hasOwnProperty(slotName)) continue;
json += "\t{\"name\":\"" + slotName + "\",\"bone\":\"root\",\"attachment\":\"" + slotName + "\"}";
curSlot++;
//omit final comma for well formed json
if(curSlot < numSlots) {
json += ",\n";
} else {
json += "\n";
}
}
json += "],\n\"skins\":{\n";
var numSkins = sizeAssocArray(skins);
var curSkin = 0;
for (var skinName in skins) {
if (!skins.hasOwnProperty(skinName)) continue;
json += "\t\"" + skinName + "\":{\n";
var skinLayers = skins[skinName];
var numSkinLayers = skinLayers.length;
var curSkinLayer = 0;
for (var i = skinLayers.length - 1; i >= 0; i
---
) {
var layer = skinLayers[i];
var placeholderName = trim(layer.name);
var attachmentName = skinName == "default" ? placeholderName : skinName + "/" + placeholderName;
var x = app.activeDocument.width.as("px") * scaleFactor;
var y = app.activeDocument.height.as("px") * scaleFactor;
layer.visible = true;
if (!layer.isBackgroundLayer)
app.activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false);
x -= app.activeDocument.width.as("px") * scaleFactor;
y -= app.activeDocument.height.as("px") * scaleFactor;
if (!layer.isBackgroundLayer)
app.activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true);
var width = app.activeDocument.width.as("px") * scaleFactor;
var height = app.activeDocument.height.as("px") * scaleFactor;
// Save image.
if (savePNGs) {
if (scaleFactor != 1) scaleImage();
if (skinName != "default") {
var path = new Folder(dir + "/" + skinName);
if (!path.exists) path.create();
}
var file = new File(dir + "/" + attachmentName);
if (file.exists) file.remove();
activeDocument.saveAs(file, new PNGSaveOptions(), true, Extension.LOWERCASE);
if (scaleFactor != 1) stepHistoryBack();
}
if (!layer.isBackgroundLayer) {
stepHistoryBack();
stepHistoryBack();
}
layer.visible = false;
x += Math.round(width) / 2;
y += Math.round(height) / 2;
if (attachmentName == placeholderName) {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}}";
} else {
json += "\t\t\"" + placeholderName + "\":{\"" + placeholderName + "\":{\"name\":\"" + attachmentName + "\", \"x\":" + x + ",\"y\":" + y + ",\"width\":" + Math.round(width) + ",\"height\":" + Math.round(height) + "}}";
}
//omit final comma for well formed json
curSkinLayer++;
if(curSkinLayer < numSkinLayers) {
json += ",\n";
} else {
json += "\n";
}
}
json += "\t\}";
//omit final comma for well formed json
curSkin++;
if(curSkin < numSkins) {
json += ",\n";
} else {
json += "\n";
}
}
json += "},\n\"animations\": { \"animation\": {} }}";
if (saveJSON) {
// Write file.
var file = new File(dir + name + ".json");
file.remove();
file.open("w", "TEXT");
file.lineFeed = "\n";
file.write(json);
file.close();
}
}
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
// Unfinished!
function hasLayerSets (layerset) {
layerset = layerset.layerSets;
for (var i = 0; i < layerset.length; i++)
if (layerset[i].layerSets.length > 0) hasLayerSets(layerset[i]);
}
function scaleImage() {
var imageSize = app.activeDocument.width.as("px");
app.activeDocument.resizeImage(UnitValue(imageSize * scaleFactor, "px"), undefined, 72, ResampleMethod.BICUBICSHARPER);
}
function stepHistoryBack () {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( "HstS" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Prvs" ));
desc.putReference(charIDToTypeID( "null" ), ref);
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
}
function getLayers (layer, collect) {
if (!layer.layers || layer.layers.length == 0) return layer;
for (var i = 0, n = layer.layers.length; i < n; i++) {
// For checking if its an adjustment layer, but it also excludes
// LayerSets so we need to find the different types needed.
//if (layer.layers[i].kind == LayerKind.NORMAL) {
var child = getLayers(layer.layers[i], collect)
if (child) collect.push(child);
//}
}
}
function trim (value) {
return value.replace(/^\s+|\s+$/g, "");
}
function hasFilePath() {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
return executeActionGet(ref).hasKey(stringIDToTypeID('fileReference'));
}
function showDialog () {
if (!hasFilePath()) {
alert("File path not found.\nYou need to save the document before continuing.");
return;
}
var dialog = new Window("dialog", "Export Layers");
dialog.savePNGs = dialog.add("checkbox", undefined, "Save PNGs");
dialog.savePNGs.value = savePNGs;
dialog.savePNGs.alignment = "left";
dialog.saveTemplate = dialog.add("checkbox", undefined, "Save template PNG");
dialog.saveTemplate.value = saveTemplate;
dialog.saveTemplate.alignment = "left";
dialog.saveJSON = dialog.add("checkbox", undefined, "Save JSON");
dialog.saveJSON.alignment = "left";
dialog.saveJSON.value = saveJSON;
dialog.ignoreHiddenLayers = dialog.add("checkbox", undefined, "Ignore hidden layers");
dialog.ignoreHiddenLayers.alignment = "left";
dialog.ignoreHiddenLayers.value = ignoreHiddenLayers;
dialog.saveSkins = dialog.add("checkbox", undefined, "Save skins");
dialog.saveSkins.alignment = "left";
dialog.saveSkins.value = saveSkins;
var scaleGroup = dialog.add("panel", [0, 0, 180, 50], "Image Scale");
var scaleText = scaleGroup.add("edittext", [10,10,40,30], scaleFactor * 100);
scaleGroup.add("statictext", [45, 12, 100, 20], "%");
var scaleSlider = scaleGroup.add("slider", [60, 10,165,20], scaleFactor * 100, 1, 100);
scaleText.onChanging = function() {
scaleSlider.value = scaleText.text;
if (scaleText.text < 1 || scaleText.text > 100) {
alert("Valid numbers are 1-100.");
scaleText.text = scaleFactor * 100;
scaleSlider.value = scaleFactor * 100;
}
};
scaleSlider.onChanging = function () { scaleText.text = Math.round(scaleSlider.value); };
var confirmGroup = dialog.add("group", [0, 0, 180, 50]);
var runButton = confirmGroup.add("button", [10, 10, 80, 35], "Ok");
var cancelButton = confirmGroup.add("button", [90, 10, 170, 35], "Cancel");
cancelButton.onClick = function () { this.parent.close(0); return; };
runButton.onClick = function () {
savePNGs = dialog.savePNGs.value;
saveTemplate = dialog.saveTemplate.value;
saveJSON = dialog.saveJSON.value;
dialog.ignoreHiddenLayers.value;
scaleFactor = scaleSlider.value / 100;
saveSkins = dialog.saveSkins.value;
main();
this.parent.close(0);
};
dialog.orientation = "column";
dialog.center();
dialog.show();
}
function sizeAssocArray(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
}
The sorting is needed for skins. Without sorting a skin might show up twice. I'll see if there is a bug with draw order but when I did testing with it I didn't run into any problems. It should only be sorting the top level layer groups, maybe it isn't. Do you have a Photoshop file you can share so I can reproduce ?
Well.. All I know is that the draw order was screwed with the sort and fine without it. I'll get a share for a test file that demonstrates this setup.
EDIT:
here you go...
The arms are messed up with the normal export script but fine when I comment the sort out.
Thanks, I'll take a look at it as soon as possible.
Hi Everyone,
I am having some problems using the Photoshop Script for exporting the graphics with the skins
Here you can see a screenshot of my Photoshop file set up
However every time I run the script I get this error
Any idea of why that is happening?
Thanks,
Raul
I have the exact same problem. Support from you guys would be great!
OK, I think I found out what the problem is. There needs to be at least one layer with opaque pixels that is NOT inside of a group. Why this does happen though is a complete mystery to me – I'm just happy that I don't have to assemble all this by hand now.
Are you using the latest script for Gist?
https://gist.github.com/NathanSweet/c8e ... 9dedd56e8c