C
chase-cc

  • 3 set 2019
  • Si è iscritto 28 nov 2018
  • sorry to dig this up, gonna add some of my own observations.

    i've gotten a customizable character working with spine, and the sprites are coming from SpriteAtlas and SpriteAtlas variants alright.

    I've noticed a bug where spine isn't honoring the scale setting of the SpriteAtlas variant (was trying to make a low-res texture set for zoomed out views). it looks like spine is just grabbing the same coordinates from the atlas in absolute coordinates instead of some relative coordinate space like UVs. For example, where it should be grabbing one hand graphic, there's actually 4 hands, as if it's copying the original unscaled hand's pixels from the now-shrunk-atlas and accidentally grabbing nearby sprites

    Presumably i need to tweak ToAtlasRegion to return the adjusted region?

  • Nate ha scritto

    It may be easiest for you to manipulate draw order at runtime. Eg, after applying animations, if animation X was applied then ensure these slots are above these other slots.

    I could try that. is there a method i can call to manipulate it at runtime? or do i just have to set up my own thing to adjust the order of Skeleton.drawOrder?

    In some ways I could see that being kind of a pain in the butt to get right. We want to have the animation drive the draw order (i.e. allow the order to change at some arbitrary time mid-animation), so we'd probably have to use spine events. I'd guess the animator would need to supply the index as an event parameter to bump the slots. This could be fairly error prone since they can't really preview the outcome in the tool

    Tangential question: If i pursue this, is there some way i can get the spine tool to treat draw order as we are intending to in Unity? Perhaps recompile a DLL and drop it in for the editor to use or something? 🙂


    quick follow up, i think i've fixed any edgecases i was seeing rather simply.

    In Skeleton.cs, i build an ExposedList<Slot> of the original slot order at the same time the drawOrder list is being constructed. I then added a method ResetDrawOrder() that clears the current drawOrder and copies the values from the original slot order list.

    From there, i just call ResetDrawOrder whenever i set a new animation or whenever i set an empty animation. Hopefully that's enough to get the job done 8)

  • We have a spine that uses multiple tracks -
    track 1 - base animation. for idle, walking, etc.
    track 2 - for special overrides when you have something equipped in your right hand
    track 3 - for special overrides when you have something equipped in your left hand

    for tracks 2 & 3, we've placed keyframes in some of these animations that nudge the draw order of slots

    example: unsheathing a sword from behind your back should move the sword from behind the character to in front of it. if we want to unsheath two swords independently of each other, each track animation will have a keyframe to nudge the relevant slots around.

    from what i've gathered, it seems spine doesn't handle this set up well. It seems that the draw order timeline for the highest track stomps on any draw order changes done by tracks beneath it. In other words, a keyframe that adjusts the draw order ends up being like an absolute snapshot of the draw order for the entire rig, instead of just relevant slots you want to move around.

    It looks like the json for a spine only includes the relevant draw order changes for a keyframe, so I was thinking of doing something like this in DrawOrderTimeline.Apply -

    for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++)
    {
       if (drawOrderToSetupIndex[i] != i)
       {
          drawOrderItems[i] = slotsItems[drawOrderToSetupIndex[i]];   
    } }

    basically i just tweaked this loop to only update the draw order if the draw order from the json is different (otherwise it will just use whatever draw order was set previously)

    this kinda seems to work, but there's some loose ends and little bugs this introduces. for example, i often clear a track by calling SetEmptyAnimation on the track, but it unfortunately isn't resetting the draw order here.

    I can try to chase down all the edgecases, but i figured I'd shoot a message here in case this is a solved problem already.

    Thanks!

    also i'm curious, is there an advantage to treating draw order the way spine does? opposed to just introducing a z axis? it feels very rigid, but i suppose it's simpler/more straightforward

    • Modificato
  • I ended up getting this working actually.

    My steps:

    1. import a bunch of textures into unity (head, torso, forearm, upper arm, etc)
    2. make a SpriteAtlas that contains those textures.
    3. make an asset bundle that contains the SpriteAtlas
    4. at runtime, download the asset bundle, load the SpriteAtlas, and get the Sprites from the atlas.
    5. pass the sprites to Spine to packed up

    The thing that was tripping me up is that you have to go into the Editor Settings and change the Sprite Packer Mode to "Always Enabled". If you build asset bundles in a separate Unity project, you must set it to Always Enabled in BOTH projects for this to work.

  • is it possible to bake some of my textures into a SpriteAtlas and use that for spine mix and match equipping? it seems to be failing in AttachmentTools when trying to get the sprite.texture (the texture is null and from what I can gather, not accessible). is there some other way to do this?

  • yeah i've noticed that.

    I think the right set of settings for straight alpha is to use the Spine/Straight Alpha/Skeleton Fill, it seems to work.

    I think when i wrote my first post, i was trying that shader, but i was getting bad results because of the way i was reading the pixel array. I was trying to use Texture2D.GetRawTextureData to read & write pixels without allocation, but for some reason it was only returning like every other column of pixels at the time, result in a really crazy looking texture. In hindsight, I was probably not calling GetRawTextureData correctly. I may have been using <Color> instead of <Color32>

    Anyways, will probably try precomputing PMA and bundling the data as a text file eventually.

  • hi, I've been getting along with the spine repacking feature for equipping/unequipping stuff - it's a pretty cool system that i've almost got working perfectly.

    I noticed that this feature is not well suited for mobile, though - the repacking feature allocates tons of textures (even with caching), so I've been trying to eliminate these things by rewriting parts of the library to re-use textures, etc.

    The last problem I've ran into is PMA related issues when we call Spine.Attachment.GetRemappedClone(sprite, sourceMaterial). I really want to avoid having this method create a new texture with PMA, so what can I do to avoid the types of issues outlined in this guide (Premultiplied Alpha Guide) ?

    The sprites i'm currently passing in are "Straight Alpha", but I've tried redoing the sprites to have PMA, and I've tried all the different included spine shaders, but I haven't unlocked the secret combo. Maybe there's a secret sauce here?

    I think the last ditch effort would be to just precalculate the PMA for a sprite and save that data to a text file/byte array. then read that at runtime (instead of the sprite). i'm not sure how well that would work across various platforms.

  • We've got a decent customization system set up here with the Runtime Repacking setup. Pretty cool. It occurred to me, that it would be pretty neat if we could turn this into a tool to build lots of NPCs in the game.

    I can pretty easily save the repacked atlas somewhere if we're running the game in the Unity Editor, but I'm unsure about the skin data. Any ideas here? Skin.cs is not serializable, but perhaps there's some bit of code in the runtime that can reserialize the Skeleton into a json blob?

  • yeah so we realized that if the SkeletonData scale is set to 1.0 and our 'equippable' images are set to 1.0 for their Pixels per Unit (PPU), it looks just fine. Basically:

    PPU = 1 / Scale
    or
    Scale = 1 / PPU

    with that relationship in mind, you just need to counter weight the value if you decide to change one of them.

  • the rig the artists gave me has a mix of parts/bones/whatver you want to call them - they've turned some of them into a mesh in the spine tool, and others are not meshes (presumably a quad or something).

    I'm trying to set this up for runtime repacking and it seems the scale of the textures are seriously out of sync for the non-meshed parts. The textures for the non-meshed parts appear to be 10x larger, at least. note that in the repacked skin atlas, the textures are all the correct size as well.

    Any ideas here? should we just turn everything into a mesh? Is there a particular area of the spine runtime code I can look at to see where it's scaling this stuff?

    perhaps the intention here is to set your individual sprites to all have a pixels per unit value set up to be scaled -just right- ?

    • Modificato
    • Modificato
  • this probably isn't a very practical working example, but if you attempt to unequip the last attachment on a spine, AtlasUtilities.GetRepackedAttachments will cause an exception on this line-

    newTexture.anisoLevel = texturesToPack[0].anisoLevel;

    basically a little bit above that line, it has no source attachments to loop through so texturesToPack will be empty.

  • well, our avatar spine is coming at one 4096x4096 texture and one 2048x2048 texture for the leftovers. should they be this big? I don't know.

    I realized I can pass GetRepackedSkin the output material...perhaps I should just have multiple output materials that I pass to this function? depending on which atlas page it's on? I'm not so sure that will work as it ultimately just loops through & repacks all the attachments on the skin (I think).

    it seems like the system is close to supporting multiple Runtime materials if it isn't already, right? like as it's looping through the attachments, it probably just needs to make sure it's only grabbing attachments for the current atlas page?

    • Modificato
  • So I've been diving into the repacking feature for equipping parts on your avatar.. more or less following the Runtime Repacking method here - http://esotericsoftware.com/spine-unity-mix-and-match

    This seems to work ok, however I have a question related to our setup. The artists have given us a rig that has so many attachment slots that they can't fit into 1 material. E.g. we have a spine skeleton whose Atlas asset has two pages (& two materials)... At runtime, I've managed to parse through the atlas to find the right source material for repacking and can equip parts, BUT:

    It seems like the API for repacking doesn't support ending up with multiple materials...is that correct? Consider the example where I end up equipping so much gear that it can't fit on to the repacked texture. Then what? lol