colinday

  • 8 de Jun de 2016
  • Se unió 25 de Sep de 2013
  • I've got a character model with a couple of skins

    1) Light (a light armor look)
    2) Heavy (a heavy armor look)

    I'm using Unity, and the SkeletonAnimation component has an "Initial Skin" option, from which I can select the light or heavy option and the character appears in game correctly with the expected skin.

    However, I now want to change the skin at runtime and am having an issue where not all slots are changing to the new skin data. I think this has something to do with the fact that not all slots have data for all skins since slots which have data in all skin sets seem to be switching at runtime properly. In the following example you can see I have two "skirt" nodes in the hierarchy,

    1) Waist [ColorSkirtA] - this has an animated mesh skirt in the light skin only
    2) Waist Heavy Skirt - this has an animated mesh skirt in the heavy skin only

    In the game, I have the initial skin set to "Light" , which displays fine ... but when I set the skin to "Heavy", there are still data from the light skin shown ... in particular the light skirt is easily seen.

    Any ideas on what code is the culprit here and not properly taking care of the skin switch properly and what I should do about it? I'm changing the skin at the runtime using

    Skeleton.SetSkin( "Heavy" );

  • I would like to use a different material to render a weapon attachment image in a slot of my spine rig. Is this possible? The slot will have a weapon image just behind the normal weapon graphic slot ... but my shader will render the image in all white with an applied color to make a magical "glow" around the foreground weapon.


    14 Dec 2015 12:21 pm


    And actually ... the Spine editor happens to do exactly what I want as the visual for a an image selection .. it makes an outline of the image for a "halo" effect ... I don't suppose the technology that does that could be made available to the runtime? 😉

  • Thanks Nate. I didn't know about the find and replace ... that's handy. I was able to get my rig using the up-ressed images by importing the JSON pointed at the new images with a scaling factor. It seemed to translate almost everything OK except for some positions of eyes and mouth on only one of my 20 heads for some reason, but totally doable.

    Now I just have to tweak all the vertices for the new image sizes a little since I added some padding to them (the process makes adding future vertices outside of pixel data a bit easier) and fix any nodes that didn't have the right scaling because it wasn't consistent for me across all images from low to high.

    Thanks much.

  • Thanks Nate.

    I've been a little sloppy with the images in this part of the project, so I don't have a uniform or well known new size that I can easily use a scalar for.

    I was doing a little experiment by exporting to JSON and then editing the exported text to point to my hi-res art and changing the "width" and "height" to be the correct new image size. Then I imported the JSON into a new project and it seemed to do what I wanted.

    I'm currently in the process of just writing a little script that rips though my JSON and does the text replacement to the high resolution image with the corrected size ... does that seem like a reasonable approach or is there other data that I'll be missing in the conversion in this manner?

  • Back when I started my project I didn't understand correctly that one could create high resolution art, and then when exporting the atlas in Spine you can just select a scalar to create a smaller atlas suitable for a game runtime. Therefore, I have a set of high resolution images in Photoshop, and then a set of scaled down layers that are at a suitable size for the game runtime ... all my Spine animation data was created using these scaled down low resolution exported .png files.

    So, I'm wondering i if I can correct this situation now even if its a pain to do once. If there is no way to do what I want from within the tool, perhaps there could be something done by exporting to a text format, running some tool over it, and re-importing it into Spine?

    My first issue ... when switching a mesh that was deformed to use my high resolution image, the vertices are at the position for the old image size as seen in the screenshot attached. You can visually see that it would be a pretty easy scaling transformation that could get my vertex data from the old low resolution position to a new high resolution position .... I'm not not sure how to go about doing it.

    Any thoughts much appreciated.

  • My mistake ... I was only questioning it because I saw within the code things such as

    _boneMaterial = new Material(Shader.Find("Particles/Alpha Blended"));

    But if that's still OK, then no worries.

  • I saw in the release notes for the newly released Unity 5.2 the following:

    Shaders: Can not create fixed function shaders using "new Material(string)" anymore. Shaders must come from assets or be fully precompiled in the editor

    It looks like Spine was doing this ... will this upgrade to 5.2 be Spine breaking?

    The full release notes for Unity 5.2 can be found here:
    http://unity3d.com/unity/whats-new/unity-5.2

  • Multi-skeleton is certainly not broken in the tools and runtime, I am successfully using this right now on version 2.1.27 (OS X), I've only got two skeletons in a file for the human male and human female, but as you can see Spine correctly exports each of their .png, .atlas.txt, and .json.txt files for Unity.

    Looking at your error messages, one of your skeletons is referencing a few spt-archer* image files which don't exist, while two other skeletons are referencing missing L-lowerArm, and R-hand1 images ... and another (or one of the previous) is also referencing a missing head2 file.

    In order to keep my spine characters organized I use separate .psd files and subfolders. Additionally for Unity I got from the asset store a PSD->PNG tool (called "PSD Layers to PNG Files") to automatically extract all the layers from the .PSD, trim them, and place them in a folder that will be used by Spine.

  • I've been Spine on my project for well over a year now, and I think I've been using a workflow that "works", but is not necessarily the best thing I should be doing. In the past this has been the workflow:

    1) Create high resolution art in photoshop using layers
    2) Export game/low resolution .PNG files of all layers
    3) Animate using game/low resolution .png files
    4) Export animation data and packed texture
    5) Adjust scale of character in Unity runtime via the Spine "Skeleton" component "Scale" field (same component that lets you set mix times etc) to be correct for the game.

    However, I just discovered the "Scale" settings in the Spine Editor for the packed texture ... and you can even export multiple scales at the same time. So really, since I have high resolution artwork ... I should always animate using the high res artwork incase I ever need to export larger than my normal game/low resolution images such as for a website, promo video, or even decide to up-res the game?

    Besides any performance considerations of having to animate using high resolution art ... is there a reason to not animate using the high resolution art since I have it?

  • In my Unity runtime, when I create a spine enabled game object, sometimes I see the object render for one frame of the entirely wrong animation. I've tracked this down to:

    SkeletonAnimation.cs

    [SerializeField]
    private String
       _animationName;
    

    I thought it was curious that this field was serialized, and it appears that the reason is that the inspector pokes it for animation, perhaps for animation preview functionality?

    SkeletonAnimationInspector.cs

    component.AnimationName = selectedAnimationName;

    The name serialized in _animationName then appears to be used during the Awake and Reset code paths.

    Spine.AnimationState:SetAnimation(Int32, Animation, Boolean) (at Assets/Add-ons/Spine/spine-csharp/src/AnimationState.cs:200)
    Spine.AnimationState:SetAnimation(Int32, String, Boolean) (at Assets/Add-ons/Spine/spine-csharp/src/AnimationState.cs:189)
    SkeletonAnimation:Reset() (at Assets/Add-ons/Spine/spine-unity/Assets/spine-unity/SkeletonAnimation.cs:92)
    SkeletonRenderer:Awake() (at Assets/Add-ons/Spine/spine-unity/Assets/spine-unity/SkeletonRenderer.cs:147)
    UnityEngine.Object:Instantiate(Object, Vector3, Quaternion)
    

    starting with the code in SkeletonAnimation.Reset()

    public override void Reset () {
       base.Reset();
       if (!valid)
          return;
    
       state = allocateAnimationState(skeletonDataAsset.GetAnimationStateData() );  // Spellbind Edit
       if (_animationName != null && _animationName.Length > 0) {
          state.SetAnimation(0, _animationName, loop);
          UpdateSkeleton(0);  // Spellbind Edit
       }
    }
    
    
    

    When that's all happening ... later in my own code after the object instantiation I decide to play a different animation, in my case it's a "summoned" animation. The result is that for one frame I see the object in the idle pose/animation, and then the summon animation plays.

    The fact that I have a mix between my idle and summoned animation of 0 doesn't seem to help the situation, only making the _animationName field not serialized makes the issue go away for me.

    If indeed the _animationName field is supposed to be serialized (maybe this is how you intend to set a default animation for an object?), there seems to be difference of some kind when this is done during initialization and when the exact same thing might be done by the user later. For instance, even in my summoned case I am actually saying

    1) Instantiate
    2) Play idle
    3) Play summoned

    But everything is OK for me as long as _animationName is not serialized. Certainly this breaks some inspector functionality ... what's the right thing here to be looking at?

    SkeletonAnimation.cs

    // [SerializeField] // SPELLBIND EDIT, breaks some inspector functionality
    private String
       _animationName;
    

    Perhaps a better thing would be to null this field for the runtime only?

    SkeletonAnimation.cs

    // SPELLBIND BEGIN
    public override void Awake()
    {
        if (Application.isPlaying == true)
        {
           _animationName = null;
        }
        base.Awake();
    }
    // SPELLBIND END
    
    

    Thanks much.

  • BTW, I was able to simply just delete the "ghost bone" at the end of the dopesheet and all is well so I didn't do any of the JSON re-import as suggested. Also, just as a data point ... this .spine file has two skeletons, but this has happened before in a different .spine project that had only one skeleton.

  • My spine file contains a duplicate bone entry in the dopesheet at the very bottom after all other bones. The runtime appears to be seeing and using both of them as one of them contains a bad keyframe at the end, and that keyframe was causing a pop in the runtime until it was removed.

    I'm not sure how my .spine file got into this state, but it's the second time this has happened. Typically the .spine file is edited my myself and my animator going back and forth through Perforce.

    From what I can tell in the file history this time it first appeared after duplicating the animations and hierarchy for the male character and then modifying everything to become the female character. File history also shows that the extra duplicate bone changes over time.

    I'm happy to provide any number of states of the .spine file for you guys at Esoteric software and will send to your email.

    Screenshot attached.

  • Finally getting back to this. First let me respond to Nate's latest brainstorms.

    1) Duplicating the skin and animating each head. This will work allow for my animator to see both the body and head while animating which is good. Deleting those duplicated bones after animating would be good but it would make coming back and adding/tweaking animations difficult since the body is no longer there. Leaving the bones in and building a runtime skin seems like it would leave a ton of bones.
    2) Love the skeleton attachment idea, unfortunately our heads aren't just on top of bodies and are under some attachments and over others.

    Brainstorming some more here ... I thought I'd see if I could hack some stuff, so I tried on setup iterating all slots and setting all attachments to null if that attachment was under head bone hierarchy I didn't want. Then I set added a "disabled" bool in the attachment setter so that no further attachment values could be assigned. As far as the runtime this is giving me what I want by essentially "hiding" all other head attachment hierarchies except the one I want.

    This has some downsides though, and I'm wondering if you might have any suggestions

    1) Down low "disabling" attachment functionality on slots seems dirty to me ... is there a better way?
    2) It leaves the bones and slots for all the other head hierarchies in tact and presumably animating in the background. Is it possible to actually remove/delete entire bones and/or slots during a setup phase of the runtime? If so, can you point me in the right data structure direction (Unity C#)?
    3) Animating in the editor is less than ideal because my animator wants to look at one head hierarchy at a time in order to animate it, and there isn't a way to quickly turn on/off the visibility an entire hierarchy without first expanding every node and clicking the visibility of each slot. The fastest way I found to do this was show bones+slots, and then multiselect using shift and toggling the visibility dot. Please let me know if there is a faster way.

    Also, open to other approaches.

    Thanks for your time Nate!