• Unity
  • Sprite Attach Rotation Bug

  • Düzenlendi
Related Discussions
...
  • Düzenlendi

Hello,

We have an issue where an attached sprite seems to be always rotated but its ONLY for the "frontUpperArm" and "frontLowerArm" slots.

All other attachments work fine.

I don't do any rotation in code, and Ive had my artist quadruple check that the rotation is correct. And since the base spine does not have any arm issues it seems correct. When there is no attachment the default spine renders the arm parts without the rotation:

I have created a sample project.

[removed]

All you need to do is press play and you will see the attachment rotation bug. There is a very simple sprite attacher code running.

Can you advise why this rotation bug is occurring?

Thanks for attaching the sample project and sorry for the inconvenience!

The problem is that the existing attachments have a local rotation of 109 degrees relative to the bone, which you perhaps never notice when setting things up in Spine. Spine does not store rotations at the slot but instead stores them at the RegionAttachment. Now the attached Sprite needs to receive these 109 degrees of rotation as well.

The following code shows two ways how you can achieve the proper rotation:

public void AttachFrontArmSprites()
{
   // Variant A
   var skeletonComponent = GetComponent<ISkeletonComponent>();
   var slot = skeletonComponent.Skeleton.FindSlot("frontLowerArm");
   float rotation = ((RegionAttachment)slot.Attachment).Rotation;
   Shader attachmentShader = Shader.Find(DefaultStraightAlphaShader);
   attachment = sprite.ToRegionAttachmentPMAClone(attachmentShader, rotation : rotation);
   slot.Attachment = attachment;

   // Variant B
   var sourceMaterial = skeletonComponent.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial;
   var slot2 = skeletonComponent.Skeleton.FindSlot("frontUpperArm");
   Shader attachmentShader2 = Shader.Find(DefaultStraightAlphaShader);
   //attachment2 = sprite.ToRegionAttachmentPMAClone(attachmentShader);
   attachment2 = (RegionAttachment)slot2.Attachment.GetRemappedClone(sprite, sourceMaterial, applyPMA);
   slot2.Attachment = attachment2;
}

Note that there should be some null-checks added, they are left out above to keep things more compact.

@Harald thank you! This has been plaguing us for a long time! I will implement your solution. THANK YOU!!

As a small side note, that

rotation: rotation

is a cool syntax trick. I didn't know C# could do that to handle a subset of the default variables. Do you know what the term for this is?

Glad it helped, sorry to hear that it has been plaguing you for a long time!

The term is named arguments.
BTW: These are also handy to make bool arguments more readable (e.g. SetPosition(position, true) is not too well readable, but setPosition(position, inWorldSpace : true) is).