komali2

  • 3 апр 2019
  • Регистрация: 1 мар 2019
    • Изменено

    We have an animation that causes an asset change. When asset swaps are keyframed in the editor:

    asset.json

    "DANCING-ACTIVE": {
       "slots": {
          "hand-left": {
             "attachment": [
                { "time": 0, "name": "hand-left" },
                { "time": 0.3333, "name": "hand-left-wide" },
                { "time": 1, "name": "hand-left-wide" },
                { "time": 1.6667, "name": "hand-left-wide" },
                { "time": 1.7667, "name": "hand-left" }
             ]
          },
    
    

    For some reason, all asset changes work just fine when a skin is applied that refers to these assets, e.g.

    code.js

    skeleton.setSkinByName('baseskin")
    

    asset.json

    // .skins.baseskin.
    "hand-left": {
      "hand-left": {
        "name": "base-skin-medium/hand-left",
        "path": "hayleigh/hand-left",
        "x": 29.39,
        "y": 1.02,
        "rotation": 84.61,
        "width": 56,
        "height": 83
      },
      "hand-left-closed": {
        "name": "base-skin-medium/hand-left-closed",
        "path": "hayleigh/hand-left-closed",
        "x": 20.13,
        "y": -2.45,
        "rotation": 88.82,
        "width": 60,
        "height": 65
      },
      "hand-left-wide": {
        "name": "base-skin-medium/hand-left-wide",
        "path": "hayleigh/hand-left-wide",
        "x": 27.68,
        "y": 1.62,
        "rotation": 88.82,
        "width": 85,
        "height": 81
      }
    },
    

    However, if we swap to a skin that doesn't point to these assets at all, suddenly the (in this case hand) skin vanishes:

    code.js

    skeleton.setSkinByName('brows-large');
    

    assset.json

    // skins.
    "brows-large": {
      "brow-left": {
        "brow-left": {
          "name": "brows-large/brow-left",
          "path": "gerald/brow-left",
          "x": 21.54,
          "y": -3.89,
          "rotation": 165.3,
          "width": 88,
          "height": 34
        }
      },
      "brow-right": {
        "brow-right": {
          "name": "brows-large/brow-right",
          "path": "gerald/brow-right",
          "x": 17.97,
          "y": 1.63,
          "rotation": 15.52,
          "width": 54,
          "height": 29
        }
      },
      "hip-clothing-path": {
        "hip-clothing-path": {
          "type": "path",
          "lengths": [ 91.59, 193.16, 413.79 ],
          "vertexCount": 9,
          "vertices": [ 1, 117, -29.1, -0.42, 1, 1, 117, -1.63, 0.28, 1, 1, 117, 11.16, 0.6, 1, 2, 117, 61.08, 0.45, 0.5, 118, -28.82, 0.47, 0.5, 2, 117, 89.94, 0.46, 0.5, 118, 0.04, 0.49, 0.5, 2, 117, 118.79, 0.47, 0.5, 118, 28.89, 0.52, 0.5, 1, 118, 76.84, 0.62, 1, 1, 118, 101.58, -0.04, 1, 1, 117, 221.76, -0.16, 1 ]
        }
      },
      "leg-left-path": {
        "leg-left-path": {
          "type": "path",
          "lengths": [ 135.63, 254.42, 545.47 ],
          "vertexCount": 9,
          "vertices": [ 1, 36, -22.4, 2.79, 1, 1, 36, 14.25, 1.58, 1, 1, 36, 58.02, 0.14, 1, 2, 36, 101.57, 2.59, 0.5, 37, -18.68, 2.51, 0.5, 2, 36, 139.73, 2.27, 0.5, 37, 19.48, 2.19, 0.5, 2, 36, 177.89, 1.95, 0.5, 37, 57.64, 1.86, 0.5, 1, 37, 85.55, 0.15, 1, 1, 37, 128.11, -0.37, 1, 1, 36, 308.29, -1.33, 1 ]
        }
      },
      "leg-right-path": {
        "leg-right-path": {
          "type": "path",
          "lengths": [ 151.09, 275.75, 588.49 ],
          "vertexCount": 9,
          "vertices": [ 1, 49, -37.7, -0.53, 1, 1, 49, -0.69, -0.46, 1, 1, 49, 57.08, -0.36, 1, 2, 49, 112.59, 1, 0.5, 51, -27.26, 0.89, 0.5, 2, 49, 150.13, -0.02, 0.5, 51, 10.27, -0.18, 0.5, 2, 49, 186.36, -1.02, 0.5, 51, 46.51, -1.21, 0.5, 1, 51, 110.63, -1.86, 1, 1, 51, 134.65, -2.05, 1, 1, 49, 320.75, -1.52, 1 ]
        }
      }
    },
    

    How can we work around this? We'd like the assets to not disappear like this.

    Cheers, badlogic. We've experimented with that as well, but we're not clear on what "set base attachments" means. Where do we define "base attachments?"

    Furthemore, adding the skeleton.setSlotsToSetupPose() invocation doesn't solve the issue with meshes, unfortunately.


    Actually, I forgot - on the note of skeleton.setSlotsToSetupPose(), if we try to do something that only touches some of the slots, i.e. add pants to our character, it nukes the rest of the avatar and only shows the pants... but keeps animated, hilariously. Perhaps this is because we don't understand how to set base attachments?

    Based on this thread: Problem with SetSkin() to change skin at runtime (Unity) I've also experimented with mucking about with the setSkin function, like removing the final null checker and etc. That does... very strange things to the animations, but we're running out of things to try to get this working.


    The problem was that our assets were using PATH, rather than NAME, to find their assets.

    Both will "show properly" in spine, but only one is the "right way" to do things in the spine editor to have things work right in the runtimes (as evidenced by issues like this).

    I'm not fully clear on exactly what that looks like in the editor or how to explain it, but our designer will have a more detailed run down of what caused this issue sometime this week.

    Thanks for your help.

    • Изменено

    We're using pixi-spine.

    We set a skin like the following:

    skeleton.setSkin(null)
    skeleton.setSkinByName('harold')
    

    Thus we see our whole character. However, if we try to change to a new skin that overwrites all attachments/slots, like so:

    skeleton.setSkin(null)
    skeleton.setSkinByName('bob')
    

    All regions update to display what we see in the spine editor when we click that skin, EXCEPT slots that are of type "mesh" or of type "linkedmesh." For example, the color of the mesh will show RED for 'bob', and BLUE for 'harold', but if we switch from harold to bob, the mesh stays blue instead of changing to red.

    Not sure what's going on here, how can we swap over meshes as well?

    FYI For future reference, we were running into this issue if we had "flatten paths" checked in Spine export options. This made the paths not get into Atlas properly.

    Thanks, the import/export JSON bit is working well - we're gitignoring the .spine, .atlas, and .png files and working just off the JSON and the image asset folders, seems to be working decently so far. Still not ideal for multiple people working at the same time but at least easier to version control. The designers are telling me this is pretty typical for photoshop or illustrator files anyway, I guess this is just Life In the World of a Designer?

    • Изменено

    We have a usecase wherein a single "avatar" may have many hundreds (or even thousands) of skins. Think hats, shoes, etc.

    The initial iteration will have only several of these. Later iterations will add more and more. More than 1 designer will be working with this "avatar."

    Right now, it seems to us that the actual spine file can only be saved as a binary. This means that our source control can only function on it as a "single source of truth" that must be worked on by only one designer at the time. That's the first blocker for us - if there was some way to have multiple designers working on it at once and "merge" their changes, it'd be great.

    The second thing we're trying to figure out is, if indeed the Spine file can only be used as a binary, how can we ensure that one designer didn't accidentally delete a slot, skin, texture, whatever, in their work on a new skin/texture/whatever?

    We're thinking we could have as part of the commit process an automated build script on the server that runs a pre-configured build on the spine file to output the atlas, json, and png spritesheet, and then run tests to make sure everything we expect to be in the json is there. However, we aren't aware of any sort of programmatic API for the Spine editor that would allow us to hook in. For example, if we could do something like, from bash, spine build -c config.json documents/spine_avatar.spine > python test_spine_output.py that would be dope.

    What methods have other people used for a designer test workflow for the Spine editor?

    Cheers all, this is very helpful. We'll probably go down the arbitrary texture route (unless we can get hot enough servers to let users download our massive sprite)

    • Изменено

    We're making a game using Pixi and Spine, utilizing the pixi-spine library (which is built off the spine-ts library). The game is quite simply a character creator.

    Something we've been chewing on: asset management. Part of our game involves having a character that can have many hundreds if not thousands of different, say, hats, tshirts, shoes, etc.

    One strategy involved color - we've already found a solution in export all assets as white and simply tinting them. Done, custom avatar coloring.

    Now we need to figure out a good way to have pages upon pages of possible hats, tshirts, whatever.

    One solution: Having a spine character with a "tshirt" slot and "hat" slot with hundreds of attachments. Works, simply setAttachmentByName('hat', 'hatWithSkull') or whatever, fairly straightforward. However, our designers are telling us it's obnoxious to create a bunch of new attachments, that they have to manually reposition the attachment by hand for every new attachment, I guess it's not as simple as a texture swap? (if this isn't the case, I'm happy for advice on this front). Furthermore, this results in, one way or another, a monolithic character.png, character,atlas, character.json. We're trying to look into splitting this up, but we can't figure out any way of paginating - all solutions we've found, split or otherwise, require ALL assets available from the get-go (the creation of the Spine asset, before it's rendered onto the page).

    Another solution: Arbitrary texture swaps, using hackTexture or code like the following:

    this.gerald.gerald.skeleton.findSlot('hat').sprites['cool/hatRed'].texture =
            PIXI.Texture.from('/hatBlue.png');
    

    This seems... okay. It allows us to pull a given png in whenever we need it (i.e. make the above an async response to the request of fetching the hatBlue.png). However, the designers are saying this is also relatively obnoxious to ensure is placed correctly, and is a mild burden in the same vein upon the engineers. It also further restricts the variability of the assets - they must all generally be reskins, or we have to make a lot of hatBig, hatSmall, hatBigWithFeather type slots. Still, as far as we can tell, this is the only solution that doesn't require a monolith (one way or the other) atlas file + png + json.

    Another solution we've just started investigating came from this post: http://esotericsoftware.com/forum/Animations-synchro-in-the-previews-and-in-the-engine-11563?p=51901&hilit=spine+skins+view#p51901

    Basically, a character with tons of different skins/skin placeholders, which refer to different attachments/slots. The designers are loving this because they say they don't have to re-place assets manually when they add new ones, but as far as we can tell this doesn't solve the monolith problem.

    The only solution we've come up with outside arbitrary texture replacement involves creating many-skinned (or attachment'd) separate character spine assets, but with only "hat" or "tshirt" textures/attachments. Then, creating these invisibly, and stealing their attachments off using methods like findSlot('hat').setAttachment(attachmentFromInvisibleOtherSpine). This I guess works but feels hacky.

    So, what sort of workflows have other found to work when potentially needed tens of thousands of assets to be swapped in/out on a whim, needing pagination for assets, etc?