• Unity
  • Using 'Flatten Paths' and skins causes import issues

When using skins in Spine the name the imported json (Exported with Official spine plugin from photoshop, skins create new folders for each skin) assigns sprites is something like "Hippo/Blue_hippo_Left_Leg"

When I export the atlas with the "Flatten paths" option the atlas.txt file then has the entries as "Blue_hippo_Left_Leg"

When I import the Skel and Atlas into Unity, The skel file is looking for an atlas with "Hippo/Blue_hippo_Left_Leg" while the atlas only lists "Blue_hippo_Left_Leg".

If I do not use flatten paths when exporting I get the whole directory in the atlas.txt file which has the same issue.

I had alway used Flatten paths when exporting but now that I am using skins I have to manally add the "Hippo/" to each item In the atlas.txt file so that unity will import it properly.

How can I use flatten paths option with skins for Unity? I feel like I am missing something obvious

Thanks for the help

Related Discussions
...
  • Змінено

Which version of the Spine Editor and the Spine-Unity runtime are you using? We had this bug once, but it should be resolved already.

Harald написав

Which version of the Spine Editor and the Spine-Unity runtime are you using? We had this bug once, but it should be resolved already.

I am using version 3.6.53


'3.7.85
7 Jan 2019

  • Fixed texture packing Image folders along with JSON/binary export not removing images path from texture region names.'

Is this the fix I need do you think?


I upgrade to this version and I still have the same issue.

Please note that the Spine Editor and Spine-Unity runtime major/minor versions have to match (so both must be 3.7).
Did you update both the Spine Editor and the Spine-Unity runtime and then re-export your assets?

Harald написав

Please note that the Spine Editor and Spine-Unity runtime major/minor versions have to match (so both must be 3.7).
Did you update both the Spine Editor and the Spine-Unity runtime and then re-export your assets?

I had done a fresh install of this runtime: https://esotericsoftware.com/files/runtimes/unity/spine-unity-3_7-2019-06-17.unitypackage

Same issue of the skel looking for sprites with the "Hippo/" prefix while the atlas.txt does not have it.

Have you also tried the latest version of the Spine 3.7 Editor and the latest 3.7 spine-unity runtime?
For example 3.7.92 fixed this issue:

Fixed atlas packing during data export always combining subdirectories when Image Folders is chosen.

How did you export the skeleton and atlas files? Did you export both at once via the Export dialog, or did you use Spine - Texture Packer to export the atlas separately?

If the problem still persists with the latest versions, could you please send us your Spine project directory (including the images) as a zip file to contact@esotericsoftware.com, then we can have a look at the issue.

5 днів пізніше
Harald написав

Have you also tried the latest version of the Spine 3.7 Editor and the latest 3.7 spine-unity runtime?
For example 3.7.92 fixed this issue:

Fixed atlas packing during data export always combining subdirectories when Image Folders is chosen.

How did you export the skeleton and atlas files? Did you export both at once via the Export dialog, or did you use Spine - Texture Packer to export the atlas separately?

If the problem still persists with the latest versions, could you please send us your Spine project directory (including the images) as a zip file to contact@esotericsoftware.com, then we can have a look at the issue.

I upgraded to 3.7.94 and have the same problem.
I use Texture Packer for the Atlas.
I emailed and sent an example directory, spine project file, exported atlas and skels that have the same issue.

If I am understanding correctly, you are packing at atlas with paths like Hippos/Images/Hippo/Blue_hippo_Left_Leg while the Spine Runtimes are looking for regions named like Hippo/Blue_hippo_Left_Leg. When you pack the images, if you specify the Hippos/Images as the root folder to pack, the attachment names are relative to that, eg Hippo/Blue_hippo_Left_Leg.

If the problem is that you have many images folders in different places, you could consolidate them and change the images paths in your projects. Eg:

Images/Hippo/Blue_hippo_Left_Leg.png
Images/Dinosaur/something.png
Hippo/Hippo.spine
Dinosaur/Dinosaur.spine

In each project, you'd use an images path of ../Images (which is relative to the .spine file location). Of course, if the only thing in the Hippo or Dinosaur folder is a Spine project then you might as well move them up a folder, but it's common to have a PSD and other files for each project.

Another option is to write a script and copy the image files to a single folder, then pack that folder. Doing that is less convenient, since you need to pack by running the script rather then from Spine. Spine can pack from the command line:
Export - Spine User Guide: Command line

Nate написав

If I am understanding correctly, you are packing at atlas with paths like Hippos/Images/Hippo/Blue_hippo_Left_Leg while the Spine Runtimes are looking for regions named like Hippo/Blue_hippo_Left_Leg. When you pack the images, if you specify the Hippos/Images as the root folder to pack, the attachment names are relative to that, eg Hippo/Blue_hippo_Left_Leg.

If the problem is that you have many images folders in different places, you could consolidate them and change the images paths in your projects. Eg:

Images/Hippo/Blue_hippo_Left_Leg.png
Images/Dinosaur/something.png
Hippo/Hippo.spine
Dinosaur/Dinosaur.spine

In each project, you'd use an images path of ../Images (which is relative to the .spine file location). Of course, if the only thing in the Hippo or Dinosaur folder is a Spine project then you might as well move them up a folder, but it's common to have a PSD and other files for each project.

Another option is to write a script and copy the image files to a single folder, then pack that folder. Doing that is less convenient, since you need to pack by running the script rather then from Spine. Spine can pack from the command line:
Export - Spine User Guide: Command line

If for example I used the spine photoshop script to export and get a folder structure like this:

Hippo_Images/Blue_Hippo/<Image_name>
Hippo_Images/Pink_Hippo/<Image_name>
Dino_images/Blue_Dino/<Image_name>
Dino_images/Pink_Dino/<Image_name>

The "<Character>Images" and the "<Skin><Character>" folders were both created by the spine plugin. All spine project files are within the "<Character>_Images" folder. All folders are within a folder called "Animations" (e.g "Animations/Hippo_Images/Blue_Hippo/").

Then I want to export an atlas that includes both the Dino and Hippo sprites and both of their respective skins, I chose to export from the "Animations" folder with "Combine sub directories" option enabled.

If I used flatten paths I get "<Image_name>" in the atlas.txt. If I don't use flatten paths I get "Hippo_Images/Blue_Hippo/<Image_name>" in the atlas.txt. While the skel is still looking for "Blue_Hippo/<Image_name>" as that is what it is called in the Spine project (Which was a name give it by importing the json that the photoshop plugin had exported).

Am I correct in saying that you suggest I add everything (All of the two character sprites for each skin) into a common "Images" folder and export from that?

If so, why does the Spine Photoshop plugin export skins in a different folder if it will have this issue? and why would I use the "Combine Sub directories" option for exporting an atlas with multiple characters if the folder name for each character is going to be a factor that prevents me from importing into unity?

Dean_Sim написав

Am I correct in saying that you suggest I add everything (All of the two character sprites for each skin) into a common "Images" folder and export from that?

Yes, this is the simplest solution.

Dean_Sim написав

why does the Spine Photoshop plugin export skins in a different folder if it will have this issue?

The Photoshop script writes images with paths like skinName/layerName.png (assuming you don't use the [folder] tag on groups to add more to the path). For example, Blue_Hippo/Image_name.png. You choose the output folder when you run the script. I'm assuming you chose Hippo_Images as the output folder, and that is why you ended up with Hippo_Images/Blue_Hippo/Image_name.png.

Note if you leave the output folder blank, it will use the folder that contains the PSD file. It shows the path it will use for the output folder below the output folder field. Space is limited so it is often truncated, but you can mouse over it to see the full path in a tooltip.

Later when you exported the Dinosaur, I would guess you chose Dino_images. In both cases, when running the script you can choose the same output folder, which allows you to easily pack that one folder into an atlas.

Dean_Sim написав

why would I use the "Combine Sub directories" option for exporting an atlas

You'd use it when you want to use folders to organize your images, but you don't want the folders to cause those images to be packed on separate atlas pages. Note that combine subdirectories doesn't strips the folders from the paths, it is separate from the setting that does that, flatten paths.

There are many uses for texture packing. Eg, you can use flatten paths if you write code at runtime that strips off the "subdirectory" of the path. Let me know if you'd like to pursue that and I can show how it is done. The main downside to flatten paths is that since the folder names are discarded, your image file names must be unique. For example, you can't have eyes.png in two different subdirectories (packing will show an error).

The Photoshop script writes images with paths like skinName/layerName.png (assuming you don't use the [folder] tag on groups to add more to the path). For example, Blue_Hippo/Image_name.png.

So the photoshop script adds the 'SkinName' folder and the spine project file that I get from the export (From importing the json that the plugin exports) has the relevant sprites named "skinName/layerName.png".
Then when exporting under these default settings, the skel file will be looking for "skinName/layerName" as that is the name the exported json gave the project file. Then If I used Flatten Paths while exporting from the default folders created by the photoshop plugin, flatten paths will always remove the "skinName/" from it atlas.txt as the plugin nested the sprites within the "SkinName" folder.

This means by default, using the flatten paths setting while having set up skins in photoshop and exporting with the plugin does not work? Why would the plugin create a file structure and name convention in the json that will not match if the user exports with Flatten paths?

Yes, this is the simplest solution.

Would this not have the same issue as above? by default the project created by the exported json file gives the sprites used by the skin the "skinName/layerName" name, which is what the skel will look for. While if all sprites are exported from one folder to an altas, the atlas.txt will not contain "skinName/layerName" regardless of if flatten paths is used as there is no such folder in this scenario.

assuming you don't use the [folder] tag on groups to add more to the path)

In the same vain, using the [folder] tag before exporting will cause the same issues. Why would I want to do this, as again exporting the atlas with flatten paths will remove the "folderName/" from the atlas.txt and have it not match the name in the project (And thus what the skel is looking for) that was made by the exported json.

It just seems like the Flatten paths setting negates the [Skin] and [folder] features as they are set up by the photoshop plugin?
requiring me to redo the folder structure created, rename the effected sprites in the project and then reset broken references for all the effected sprites that had to be renamed.

Dean_Sim написав

So the photoshop script adds the 'SkinName' folder and the spine project file that I get from the export (From importing the json that the plugin exports) has the relevant sprites named "skinName/layerName.png".
Then when exporting under these default settings, the skel file will be looking for "skinName/layerName" as that is the name the exported json gave the project file. Then If I used Flatten Paths while exporting from the default folders created by the photoshop plugin, flatten paths will always remove the "skinName/" from it atlas.txt as the plugin nested the sprites within the "SkinName" folder.

All of this is correct!

Dean_Sim написав

This means by default, using the flatten paths setting while having set up skins in photoshop and exporting with the plugin does not work? Why would the plugin create a file structure and name convention in the json that will not match if the user exports with Flatten paths?

As you say, it does not make sense to use flatten paths when setting up skins and using the Photoshop script (or any time you use folder paths in your attachment names/paths). Texture packing has many settings and many uses, even beyond using an atlas with skeleton data. There are a number of combinations of settings which may not do what you need for your particular setup.

Dean_Sim написав

It just seems like the Flatten paths setting negates the [Skin] and [folder] features as they are set up by the photoshop plugin?

Correct. If you are using folders (prefixes with slashes /) in your attachment names then most often it does not make sense to use flatten paths, which removes the folder prefixes. Though someone could do that and then at runtime write code to strip the folder prefix from the attachment names/paths, so the regions can be found in the atlas. There is a lot of flexibility in how this works to allow for everyone's needs to be met. In general, most people should not use combine subdirectories for use with skeleton data.

At the risk of going off on a little tangent, pack settings can be specified per folder by using a pack.json file in each folder. One use of flatten paths is to have a folder that uses subfolders for organization, but you don't want those subfolders in the region names. Eg:

images/
images/cat/
images/cat/pack.json
images/cat/head/head_green.png
images/cat/head/head_red.png
images/cat/body/body_green.png
images/cat/body/body_red.png

In the images/cat/pack.json you can specify to use flatten paths, then the atlas would have regions named:

images/cat/head_green
images/cat/head_red
images/cat/body_green
images/cat/body_red

A setup like this is probably not for use with skeleton data, but might be used for other texture atlas use in games/applications. Using a pack.json to specify per folder settings can be useful for use with skeleton data though, for example to strip or not strip whitespace on only some folders of images, to control the page size for each folder, etc. Note that if you are texture packing as part of skeleton data export and you choose to pack Attachments, the pack.json files are not used. You need to either choose to pack the Images folder or run the texture packer separately from skeleton data export.

BTW, if you are moving your images around, you can use Find and Replace to fix up attachment names/paths:
Tree - Spine User Guide: Find and Replace

However, as described above, I believe all you need to do is 1) move your images into a common image folder, and 2) change the images path in each of your Spine projects to point to the common images folder. When packing a texture atlas, you'd pack the common images folder (using combine subdirectories if you want a single atlas page). Later if you use the Photoshop script again, either be sure to set the output folder to the common image folder OR output to some other folder and then when you are happy with the files, copy them into the common image folder.

So I have three options:

1) For each and every character, move our skin images into a common image folder of that character (So that folder contains all images for that character) and then change the images path for the skin images in my Spine project to point to the common images folder of that character. Use combine directories and flatten paths to export an atlas for all characters to be in an atlas. Repeat this for every new character. Also, in order to change skins in the spine project have different names for the different skin sprites and find and replace to rename to skin sprites in the project (found in the same folder) in order to change skins for different animations.

2) Don't use [Folders] or [Skins] and continue to use combine subdirectories and flatten paths with the default folder structure we currently use.

3) Write a script to strip the folder prefix from the attachment names/paths, so the regions can be found in the atlas.

It seems like there should be an option for texture packer when using combine subdirectories and subsequently flatten paths to exclude removing established skin folder names when exporting the atlas. Is there anywhere I can formally submit this to you guys as a feature recommendation?

I feel like it would be nice for the features to work together in this manor as I am sure others are working on projects with folders for characters with skins and would like have it all work out of the box without having to work around it in this manor.

Dean_Sim написав

1) For each and every character, move our skin images into a common image folder of that character (So that folder contains all images for that character) and then change the images path for the skin images in my Spine project to point to the common images folder of that character.

Your wording is not super clear. You'd move the images so all characters are under a single folder, eg the folder named root here:

root/character1/red/head.png
root/character1/green/head.png
root/character2/red/head.png
root/character2/green/head.png

Then you'd change the images path under the Images node in the tree for all your projects to point to the root folder. Your attachments need to be named to match so images path + / + attachment name + .png resolves to the image file. For example, your attachment name needs to be character1/red/head (because root + / + character1/red/head + .png finds the image). You can use Find and Replace to quickly add the character1/ prefix to all attachments (enable regex, find (.+), replace with character1/$1). Or you can name a Photoshop group character1 [folder] and place your layers in that group, that way the images exported from Photoshop are in the right place.

This setup allows you to pack the root folder, which will give you an atlas where regions will be found correctly at runtime. Do not use flatten paths. Do use combine subdirectories if you don't want the folders to put images on separate atlas pages.

There could be a 4th option: write a shell script to copy your image folders from wherever they are into a single folder. Eg, if your folders look like this:

somewhere/character1/images/red/head.png
somewhere/character1/images/green/head.png
somewhereelse/character2/images/red/head.png
somewhereelse/character2/images/green/head.png

The script would copy them to:

root/character1/red/head.png
root/character1/green/head.png
root/character2/red/head.png
root/character2/green/head.png

The shell script would then pack the root folder. As above, in the atlas the regions would have names like character1/red/head. In your Spine projects you would be using the character specific images folder (eg somewhere/character1/images/) so your attachment names would have paths like red/head. That means at runtime it would look for red/head in the atlas. To remedy that you would write a little code that prepends the skeleton name. For example for a skeleton named character1 it would look for character1/red/head.

This approach allows each project to have its own image folders, the downside being you have to write a shell script to assemble the atlas, plus write a little code at runtime.

Dean_Sim написав

It seems like there should be an option for texture packer when using combine subdirectories and subsequently flatten paths to exclude removing established skin folder names when exporting the atlas.

I think it is better to know exactly what the packer will do: it will either flatten paths or not. Having it flatten paths, but not if the path is a folder for a skin seems more complicated than necessary.

Dean_Sim написав

I feel like it would be nice for the features to work together in this manor as I am sure others are working on projects with folders for characters with skins and would like have it all work out of the box without having to work around it in this manor.

We are open to suggestions on how things can be improved, though I don't think making combine subdirectories/flatten paths more complicated is the way to go. I suggest not using flatten paths at all, as it is making things harder than they should be. I suggest the approach above where you place all images in a root folder and pack that. That is the simplest way to organize your images and name your attachments, then you just pack and use the atlas at runtime.

root/character1/red/head.png
root/character1/green/head.png
root/character2/red/head.png
root/character2/green/head.png

This setup allows you to pack the root folder without using combine subdirectories, which will give you an atlas where regions will be found correctly at runtime.

If I don't use combine subdirectories when exporting with that structure, it wont generate a single atlas with all the characters and there skins in it?

I need it to be in one atlas.

Sorry for the delay. You're right, I had confused the separate settings combine subdirectories (subfolders do not cause images to go on separate pages) and flatten paths (removes folder prefixes). I've edited my posts above to fix the mistakes, in case future readers come along.

Here is my suggested organization again: You'd move the images so all characters are under a single folder, eg the folder named root here:

root/character1/red/head.png
root/character1/green/head.png
root/character2/red/head.png
root/character2/green/head.png

Then you'd change the images path under the Images node in the tree for all your projects to point to the root folder. Your attachments need to be named to match so images path + / + attachment name + .png resolves to the image file. For example, your attachment name needs to be character1/red/head (because root + / + character1/red/head + .png finds the image). You can use Find and Replace to quickly add the character1/ prefix to all attachments (enable regex, find (.+), replace with character1/$1). Or you can name a Photoshop group character1 [folder] and place your layers in that group, that way the images exported from Photoshop are in the right place.

This setup allows you to pack the root folder without using flatten paths. You can use combine subdirectories if you want the whole atlas packed on a single page. If you ever have so many images they don't all fit on one page, you can pack without combine subdirectories but place a pack.json file in the character1 and character2 folders that turns on combine subdirectories just for those folders. That way all the skins for each character are on their own atlas page.

You'd move the images so all characters are under a single folder, eg the folder named root here:
root/character1/red/head.png
root/character1/green/head.png
root/character2/red/head.png
root/character2/green/head.png
Then you'd change the images path under the Images node in the tree for all your projects to point to the root folder. Your attachments need to be named to match so images path + / + attachment name + .png resolves to the image file. For example, your attachment name needs to be character1/red/head (because root + / + character1/red/head + .png finds the image). You can use Find and Replace to quickly add the character1/ prefix to all attachments (enable regex, find (.+), replace with character1/$1). Or you can name a Photoshop group character1 [folder] and place your layers in that group, that way the images exported from Photoshop are in the right place.

This setup allows you to pack the root folder without using flatten paths. You can use combine subdirectories if you want the whole atlas packed on a single page.

That suggestion should work for my needs, ill try it out and see.

Thanks for clearing everything up for me! 🙂