• Editor
  • Mix-and-match advanced features

Hello!

I am working on a 2D ARPG where the character model can equip various weapons/armor - this could potentially be 100 different sets of armor and weapons. Currently I am doing this in Unity by attaching game objects to bones which works great, but does not allow for more complex animations that would be part of the Spine model such as mesh deformations and/or sprite frames. I know I can create a single Spine model that has every single piece of armor/weapon and I can switch them out via slots but I have a few questions about how to support such a large amount of data:

  1. For an equipment slot like the helmet can I use a single mesh that will be animated/deformed and swap out the sprite or would every single alternate helmet require it's own mesh data? I am assuming if I swap out the sprite it would need the exact same dimensions to map properly as well.

  2. Is it possible to export/import slot data or sub data separately? For example if my model file contains 100 helmet slots with mesh data, can I export them individually and then load them so that I don't have a single model with a massive amount of data? I am guessing that this is possible with some data post-processing and modifying the Spine runtime myself, but I'm curious if anyone else has already solved this issue.

  3. Along with 2 it would be great to export/import individual animations or groups of animations so that I don't have to load a single massive file with every possible animation and I can load only the specific animations that I will need during runtime.

Thank you!

  • इस पर Harald ने जवाब दिया।
    Related Discussions
    ...
    • संपादित

    Noeski
    1.) For an equipment slot like the helmet can I use a single mesh that will be animated/deformed and swap out the sprite or would every single alternate helmet require it's own mesh data?

    It is not necessary to have separate mesh data per item, and we would very much recommend against that. In general you might want to only have different meshes if you need to cover very different shapes of helmets which need to be animated differently. E.g. all bow items could share the same mesh. Otherwise you would need to setup vertex weights for each item, leading to a lot of redundant work (and also unnecessary data, increasing file size and load times). Please also have a look at how linked meshes are used in a single project to re-use a single mesh with different attachment images.

    I am assuming if I swap out the sprite it would need the exact same dimensions to map properly as well.

    Yes, the attachment image needs to be of the same size.

    Noeski
    2.) Is it possible to export/import slot data or sub data separately? For example if my model file contains 100 helmet slots with mesh data, can I export them individually and then load them so that I don't have a single model with a massive amount of data? I am guessing that this is possible with some data post-processing and modifying the Spine runtime myself, but I'm curious if anyone else has already solved this issue.

    I'm not sure I completely understand what you are planning as a setup, since "100 helmet slots with mesh data" sounds a bit like the wrong way. Why do you want to have 100 separate slots and meshes? When using linked meshes, you need all of them to be under a single slot. Having multiple slots only makes sense when the mesh differs, which should be avoided where possible, by e.g. grouping similar items and re-using the same mesh for a group.

    In general you can load atlas regions via code from just the atlas assets, without having to manually combine data of multiple skeleton data files (or skeletonData objects). You can check out how to do that in the Spine Examples/OtherExamples/AtlasRegionAttacher example scene, in the used AtlasRegionAttacher script. While this example replaces region attachments, the same applies for mesh attachments. For mesh attachments you can also check out the Spine Examples/Other Examples/Mix and Match and Mix and Match Equip example scenes.

    If you need to change more than atlas regions (attachment images) from a separate export, you would need to write your own custom import post-processing script. However, we would not recommend going down that path unless it can be avoided.

    This related post might be interesting for you as well:
    https://esotericsoftware.com/forum/d/15867-memory-management-of-character-with-many-outfits

    Noeski
    3.) Along with 2 it would be great to export/import individual animations or groups of animations so that I don't have to load a single massive file with every possible animation and I can load only the specific animations that I will need during runtime.

    Could you describe what kind of separate animations you have in mind? Likely you should be able to combine similar items to groups and then only animate each item type once. If you really need to combine animations and meshes from multiple skeleton exports to a single one, you would need to combine them programmatically and adjust referenced indices accordingly. E.g. if the first file contains bone indices from 0-100, and each additional equipment export adds e.g. 3 different new bones, they need to be added to the list of bones and then referenced as 101-103, 104-106, and so on.

    Hi Harald,

    This is super helpful, thank you.

    If I understand correctly I should setup a slot for each unique shape I would need i.e. a Sword slot vs a Dagger slot where the Sword slot would contain the mesh data required for all of the Swords in the game. How can I set this up so that these slots are still exported with the mesh data, but do not export their images so that I can keep a single base texture atlas for the character that is rendered underneath?

    For example I have this slot setup with a mesh attachment:

    Once this is setup, what is the best way to show/hide and set/unset the correct texture to the slot's attachment? I am familiar with adding/removing attachments at runtime but this would require updating an existing mesh attachment.

    Regarding separating animations, it would be to optimize loading/unloading animations on demand, the skeleton/bone data wouldn't need to be separated. Let's say for example I have an animation that only plays for a specific cinematic that I could load, add that animation to my skeleton data and then play it. This would be useful for a lot of one off situations that only play once during a game without having to load a mega file with 100s of animations.

    • इस पर Harald ने जवाब दिया।

      Noeski If I understand correctly I should setup a slot for each unique shape I would need i.e. a Sword slot vs a Dagger slot where the Sword slot would contain the mesh data required for all of the Swords in the game.

      You would normally only want to have separate slots for swords and daggers if they can be equipped (attached) at the same time (i.e. when they are not mutually exclusive). Otherwise, if you can only hold one item in the right hand, you would typically create just a single slot such as a right-hand-item slot. You can then have multiple different mesh- and region-attachments below a single slot, of which there will always be only a single one visible at the same time.

      You can also have a look at the example project that come with Spine such as Spineboy where different attachments (mouth-grind, mouth-oooo and mouth-smile) are switched out under the mouth slot, in this case controlled via animation.

      Also be sure to check out the documentation on Slots here, which might be a bit overwhelming at first but will make more sense the more you get used to Spine's design and terminology:
      http://esotericsoftware.com/spine-slots

      Noeski How can I set this up so that these slots are still exported with the mesh data, but do not export their images so that I can keep a single base texture atlas for the character that is rendered underneath?

      Do you mean you want to export placeholder attachment images as a separate atlas? In general you could precisely control which attachment images go on which atlas by packing by folder structure, as described in this forum thread:
      https://esotericsoftware.com/forum/d/17327-separate-texture-atlas-per-skinslot

      Noeski I am familiar with adding/removing attachments at runtime but this would require updating an existing mesh attachment.

      Unless I misunderstood what you mean by that, you just want to replace an existing MeshAttachment with a new one where the attachment image has been replaced. Please check out the Mix and Match and Mix and Match Equip example scenes as mentioned in a previous post on how to do that.

      Noeski Regarding separating animations, it would be to optimize loading/unloading animations on demand, the skeleton/bone data wouldn't need to be separated.

      If only animations are added, you could rather easily programmatically append the animation data from your on-demand loaded animation file SkeletonData object to your main SkeletonData object.
      See the Animations property here:
      SkeletonData.cs : L73

      • इस पर Noeski ने जवाब दिया।
      • SilverStraw ने इसे लाइक किया।

        Harald Do you mean you want to export placeholder attachment images as a separate atlas? In general you could precisely control which attachment images go on which atlas by packing by folder structure, as described in this forum thread:

        Sort of, the default case should have the character with nothing equipped so I don't really want to have the separate atlas but I haven't figured out a way to keep the slot data without exporting it with a blank image in a separate atlas like you suggested. This brings me back to my original post where I would need these attachments separated so that Spine doesn't have issues when trying to import the atlases and placeholders that are never actually used.

        • इस पर Harald ने जवाब दिया।
          • संपादित

          Noeski Sort of, the default case should have the character with nothing equipped so I don't really want to have the separate atlas but I haven't figured out a way to keep the slot data without exporting it with a blank image in a separate atlas like you suggested.

          A slot does not contain the required attachment mesh vertex position and uv data (or x/y/width/heigth/rotation data in case of a RegionAttachment), and also does not contain any atlas region data, it would not make sense to export a slot without any attachment (if you want to replace attachment images later). Each attachment under a slot has its own position and size, the slot itself is just something to pin attachments to.

          If you worry about the placeholder attachments taking up unnecessary size, you could set the placeholder atlas texture importer size to the minimum size (e.g. 32x32) in Unity to not waste any data, or replace the placeholder atlas texture at the respective Material with an even smaller generic white 1x1 texture. However, for debugging reasons you might want to keep the original placeholder atlas texture around.

          @Harald quick update - I setup a pre-processor script to move all attachments from specific slots into their own ScriptableObjects which can be loaded/unloaded and attached at runtime which is working well. Couple questions:

          1. Is there any open source library for serializing back to a json or binary format? This seems to be missing from every runtime implementation and would be nice to have!
          2. Is there going to be support for repacking Sequences? It looks like this is missing (or I can't seem to find it in the latest source.)
          1. Is there any open source library for serializing back to a json or binary format? This seems to be missing from every runtime implementation and would be nice to have!

          The core runtimes are all (almost) identical, so you will never find major features in any other runtime that is missing in spine-unity. Unfortunately there is no such skeleton json or binary serialization class available, sorry!

          1. Is there going to be support for repacking Sequences? It looks like this is missing (or I can't seem to find it in the latest source.)

          Could you please describe in more detail what exactly you want to achieve?

          I'd like to be able to remap attachments that have multiple frames . From my understanding calling GetRepackedSkin and/or GetRepackedAttachments does not copy attachments that use Sequences.

          Thanks for the clarification, good catch! I've created an issue ticket here:
          EsotericSoftware/spine-runtimes2268
          We will let you know once the issue has been fixed. It will be fixed on the 4.2-beta branch since the necessary changes are too risky to break existing 4.1 projects. Thanks for reporting!

          @Noeski This issue has just been fixed on the 4.2-beta branch (see the issue ticket here).

          Please note that the fix will not be ported to the 4.1 runtime to not break existing projects. However, since this commit is currently the only difference of AtlasUtilities.cs between 4.1 and 4.2-beta, you can simply copy the AtlasUtilities.cs file from 4.2-beta over your existing file of the 4.1 runtimes:
          https://github.com/EsotericSoftware/spine-runtimes/blob/4.2-beta/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs

          Please let us know if this resolves the issue on your end as well. Thanks again for reporting!

          • SilverStraw ने इसे लाइक किया।
          3 महीने बाद में

          @Harald coming back to this as I am running into one more issue. The changes you made for repacking sequences works great, but animations no longer work. I believe this is due to SequenceTimeline keeping a reference to the original attachment when it loads and it can no longer update correctly with a new attachment on the slot. Sort of unrelated, but why does the Sequence Timeline need an attachment? I feel like it would be more flexible if it applied to the Slot instead so you could easily swap the attachment without having an additional timeline for each one.

          The attachment itself defines the sequence. When animating the sequence playback, it's animating that specific attachment. You're right that we could have implemented it by keying it for a slot, sort of similar to path constraints, but then to have two attachments with different sequences or sequence animation, you would need two separate slots. We decided it makes more sense to key the attachment directly, similar to deform timelines.

          @Nate that makes sense - I'm wondering if there are any potential solutions for the issue I am running into though with repacking attachments that use sequences. I have a very hacky fix that replaces the check for the attachment reference in SequenceTimeline.Apply with checking that the Name on the two attachments match. The other solution would be to update the reference in all SequenceTimeline instances to the new attachment in GetRepackedSkin but that would require GetRepackedSkin to also modify the skeleton data.

          We have mechanism for sequence attachments to use the sequence (and deform) timelines for another attachment: VertexAttachment timelineAttachment. If you duplicate a sequence attachment and set timelineAttachment to the old attachment, the duplicate will use the old attachment's sequence and deform timelines.

          That may solve your problem, but note it applies for all attachment specific timelines (currently that is sequence and deform timelines). If you use a linked mesh with Inherit timelines checked, its timelineAttachment is the source mesh. You (or GetRepackedSkin, oh how I dislike that method name) probably want to set the duplicate attachment timelineAttachment to the original attachment timelineAttachment. Only if that is null would you set it to the original attachment instead.

          @Nate Ah okay that does work for VertexAttachments! Is there a solution for RegionAttachments? or would I need to makes sure any sequence attachment that I am working with that needs to be repacked is a MeshAttachment?

          Hmm. Currently it's only for VertexAttachment because that's the only place in the editor UI where you can choose to inherit timelines or not. At runtime it would be useful on RegionAttachment when duplicating a region attachment that has a sequence. We could even move the field to Attachment, even though some attachment types don't yet have timelines. We'll do this in 4.2. In the meantime I'm afraid it will only work for vertex attachments, unless you modify the runtime yourself.

          • Noeski ने इसे लाइक किया।

          @Nate great! Thank you for looking into this, I will be on the lookout for it in 4.2.