- Edited
Swapping out wearable character equipment, e.g. hats
Hello,
I've been searching for a proper solution on the forums for awhile now, and everything I've found is either somewhat outdated, or not quite relevant to what I'm trying to do. But it's completely possible I've missed something, so feel free to just link me to a relevant thread if that's the case
In our game (in Unity, of course) we have a bunch of playable characters (11) that the player can choose from, and each of those characters can wear different Gear and different Hats. The Gear and Hats are the same across all characters though, so for example you could be Donnie wearing the Jetpack Gear and Fedora Hat, or Billy wearing the Jetpack Gear and Fedora Hat, or Billy wearing the Ice Wand Gear and Fedora Hat, etc.
What I'm wondering is the best approach for sharing these swappable equipment pieces across multiple characters. From research I've already done, it seems like doing skeleton.setAttachment() (http://esotericsoftware.com/spine-runtime-skeletons#Changing-attachments) is almost what I want to do, but that assumes the swappable pieces are in the same atlas as the character animation, right? I'm inferring that from this in the getAttachment() API: "First the skin is checked and if the attachment was not found, the default skin is checked." I'm trying to avoid a situation where I have to put ALL the Gear and ALL the Hats into every characters' atlas.
Hopefully that's enough information to get started! Any ideas are appreciated
Cheers,
Chris
Im finding the same thing, look this video and FootSoldier example from runtime. But it didnt work for me Im confusing with how the SpriteAttacher works and what the problem with it
What means that error?
Exception: Attachment not found: weapon, for slot: r_hand_slot
Here is code:
[SpineSlot]
public string slot;
[SpineSkin]
public string skin;
void Start() {
var skeletonRenderer = GetComponent<SkeletonRenderer>();
var attachment = skeletonRenderer.skeleton.Data.AddUnitySprite(slot, sprite, skin);
skeletonRenderer.skeleton.SetAttachment(slot, sprite.name);
}
Oh, I have traditionally found the answer myself I got error when choosing my skin in this Script, when I choose default skin and disabled all animation finally I got the sprite was attached from another Atlass. Will work in this way, I need found how to prevent reseting the attachment by animation
Thank you
That video is extremely helpful, thank you for posting! I'm going to run a test this week using what I learned in there, I'll post back here if we run into any issues with the pipeline.
Hello! Please don't use that video as a guide for implementing equipment! It's quite an old video.
If you're on the latest runtime, see the "Mix and Match" example scene and MixAndMatch.cs
sample script.
The MixAndMatch way of doing it has a number of benefits, including:
- compatibility with animations keying the slot
- being able to repack the texture to minimize sorting glitches and draw calls.
Ah ok! Thanks for the update. Yes I had noticed it was from a couple years back, but since I was having trouble finding more recent info on this pipeline, I figured it might work (the video makes it look so simple! haha). But cool, I'll take a look at this MixAndMatch script you refer to and give it a go.
22 Jun 2017, 12:08
Ok I've been testing out the Mix and Match scene (super awesome, makes a lot of sense), and then have started bringing it over into our game flow. But I'm encountering a chain of problems, and they seem to stem from the fact that we're using SpineAnimator
instead of SpineAnimation
(so we can use the mechanim graph). Since SpineAnimator
doesn't have an AnimationState, I can't pass anything in for the third param here:
var newSkin = skeleton.UnshareSkin(true, false, skeletonAnimation.AnimationState);
But if I leave that param null, I end up getting the following error:
ArgumentNullException: Argument cannot be null.
Parameter name: region
Spine.Unity.Modules.AttachmentTools.AttachmentCloneExtensions.GetLinkedMesh (Spine.MeshAttachment o, System.String newLinkedMeshName, Spine.AtlasRegion region, Boolean inheritDeform) (at Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs:864)
Spine.Unity.Modules.AttachmentTools.AttachmentCloneExtensions.GetLinkedClone (Spine.MeshAttachment o, Boolean inheritDeform) (at Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs:788)
Spine.Unity.Modules.AttachmentTools.AttachmentCloneExtensions.GetClone (Spine.Attachment o, Boolean cloneMeshesAsLinked) (at Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs:740)
Spine.Unity.Modules.AttachmentTools.SpriteAtlasRegionExtensions.GetRepackedSkin (Spine.Skin o, System.String newName, UnityEngine.Shader shader, UnityEngine.Material& m, UnityEngine.Texture2D& t, Int32 maxAtlasSize, Int32 padding, TextureFormat textureFormat, Boolean mipmaps, UnityEngine.Material materialPropertySource) (at Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs:414)
BSpineEquipmentAttacher.Start () (at Assets/Scripts/Player/BSpineEquipmentAttacher.cs:39)
Any ideas? I hope the answer isn't "SpineAnimators are not supported for this pipeline at this time", haha.
Thanks!
22 Jun 2017, 12:16
Oh I should add that the line the error is referring, BSpineEquipmentAttacher line 39, is this:
newSkin = newSkin.GetRepackedSkin("repacked", repackedShader, out runtimeMaterial, out runtimeAtlas);
csumsky3, I also have Animator that triggered to animations what I created in Spine.
I have it worked with added atlas and thats all. Try uncheck repack and "applyHeader" and set up atlas and choose region, name, slot.
At the same time I have a problem that my attached sprite lost the position and rotation (if I only want to swap between two similar attachments from one atlas). At the last script I done it worked good, all new attachments attached exactly where they need it without any rotation or offset fields filling, but that script was crap, want to rebuild it with Mix&Match.
Could this be due to the use of cloned skin?
Or how can I get the position and rotation from, initial attachment and set it to new?
__
here is how my old crap script works: http://recordit.co/y9zoTvyzr2
@[deleted]
No, using SkeletonAnimator should be fine. They are both just SkeletonRenderers. It's ok to pass null in that method.
I'm not sure what your setup is that would cause a region not to be recognized, unless you're using TK2D or something. That's the case we currently don't support.
Ah ok, that would be it then - we are currently using tk2d. Any ideas for gear-swapping like this with tk2d, before I just have us switch these animations away from tk2d?
23 Jun 2017, 06:23
Also, is there any way to have some spine animations use tk2d, and others not? It doesn't appear to be so, but I thought I'd ask!
It should work just fine, as it does fall back to Spine AtlasAsset if the tk2dSpriteCollectionData is null, but on checking, looks like the inspector broke for it.
I'll see about fixing it. Stay tuned!
Thanks! I think if I can do that then I'll be all set For my gear-swapping anims we'll just export atlases from spine, and then continue to use tk2d for everything else.
Should be fixed on git and the latest unitypackage!
Spine Unity Download
Thanks Pharan! Is there any way to get this fix into Spine-Unity 3.5 for Unity 5.4? We haven't switched to Spine 3.6 yet, and we're still on Unity 5.5 (nearing the end of another project and it's a little too risky to upgrade right now).
This should do it.
Find your SkeletonDataAssetInspector.cs
file in your project and replace it with this: https://gist.githubusercontent.com/pharan/8c546440d6f5fe727212bcfefc30f05b/raw/84e583633581cf6c3532a8ca4db532e566623c49/SkeletonDataAssetInspector.cs
Amazing! I'll try that now.
26 Jun 2017, 09:56
Hmm even with the new script, if I try to import a spine animation without going through tk2d, I get the attached set of errors and warnings in the inspector.
26 Jun 2017, 09:58
Oops nevermind! I didn't realize I needed to assign the _Atlas file to the Atlas Assets array. Looks like it's working! I'll let you know if anything else comes up.
Good to know!
Everything seems to be working great now, thanks for all the help Pharan!