• Unity
  • [Unity] Attaching a Unity sprite always makes it rotated

Related Discussions
...

I am using Unity 5.1. Whenever I attach a Unity sprite, using AttachUnitySprite directly or with the SpriterAttacher component, my sprite ends up rotated.

I have tried disabling rotation in the texture atlas, checking the sprite packingRotation (which is None), all sorts of stuff, but it is still rotated 90 degrees to the left when I attach it.

Has anyone seen this before?

Thanks!

Edit: I changed the following in SpriteAttacher.cs, just to see what would happen:

//TODO: make sure this rotation thing actually works
      bool rotated = false;
       if (sprite.packed)
       {
           //rotated = sprite.packingRotation == SpritePackingRotation.Any; <

---

 Commented this guy out
           rotated = true;
       }

The 'TODO' is not mine, and seems pretty relevant. This change made the sprite properly rotated, but the pivot point is pretty funky. I'm not sure if that is a result of my hack, or if I just need to solve my own pivot issues. To keep it in roughly the same position, I had to set the pivot of my sprite to 'Left', which is certainly not what I'd expect. My bone goes from bottom to top.
The scale is off too. I wonder if my bone has to be the exact size of the image.
Either way, I'm not sure that I'm on the right track...
To be clear though, the sprite atlas packed by Unity did not rotate my sprite.

Yes I have had the same problem, but i solved it by counterrotating all the slots.

Yea... Unity 4.x and 5.x have different understandings of the word "Rotated" I believe.

PS:
I remember writing that snarky comment.

Thanks for the replies. I'll try to dig into it tonight to see if I can get it working.
I am more concerned now about the weird scaling. Do you have any idea what may be causing that? The image just looks a bit squished, slightly shorter and wider.

Awesome, thanks for the link. I saw the Attaching Unity Sprites to Skeletons thread yesterday and will scan it again, but the Bug thread looks particularly helpful. I'll dig more.


Well, I took a stab at the sizing issue using the method proposed in the "Bug in SpriteAttachmentLoader" post, but no luck. My sprite doesn't have alpha around it, so I guess it doesn't really apply.
I'm a bit nervous that I won't be able to find a workaround for this one..


I am also seeing this scaling issue with the Atlas Region Attacher.

I have a pretty basic setup on this one. A single bone, stretching from the origin up. A single slot is on the bone, with 2 attachments under it. All transforms are zero, except the bones rotation to make it go upwards at 90 degrees.

The Atlas Region Attacher shows the sprite rotated when I swap to the second attachment. I rotated the UVs on the attachment, so that's fine. But I still see the squished sprite, and the scaling seems wrong. So it's not just Unity sprites.


This scaling issue is driving me insane. The only way it seems to work is if I use attachments that are built into the skeleton data. Creating my own attachments, whether through atlas regions or unity sprites, just isn't working.

Have you tried changing the import setting on the sprite you are attaching from Mesh Type: "Tight" to "full rect" instead. That worked for me.

Thanks for the suggestion, but I did try that. Well, i think I did. The only way I could see to change it was via an asset post processor during import, so I think it actually changed. (Edit: Found it under 'Advanced' texture type, but still doesn't fix it.)

Also, do you have excess alpha pixels around your sprite? I figured this setting only helped in that case.


Okay, I am close.

I disabled the 'rotate' flag I have been using in SpriteAttacher. Now, the sprite is rotated 90 degrees again, but the scaling looks to be correct.

When rotating does happen, the mesh itself is not rotated, only the UVs. This means it is placing an upright UV onto a rotated mesh, resulting in the stretching.

So I have to figure out how to deal with this rotation better. Hopefully without rotating all of my sprite assets...


I added the 'rotated = true' again, so the UVs are rotated. On the attachment, I also flipped the width and the height, and it now seems to be working. This hack feels so dirty, but I may stick with it.

//do some math and assign UVs and sizes
attachment.SetUVs(texRect.xMin, texRect.yMax, texRect.xMax, texRect.yMin, rotated);
attachment.RendererObject = atlasRegion;
attachment.SetColor(Color.white);
attachment.ScaleX = 1;
attachment.ScaleY = 1;
//attachment.RegionOffsetX = sprite.rect.width * (0.5f - Mathf.InverseLerp(bounds.min.x, bounds.max.x, 0)) / sprite.pixelsPerUnit;
//attachment.RegionOffsetY = sprite.rect.height * (0.5f - Mathf.InverseLerp(bounds.min.y, bounds.max.y, 0)) / sprite.pixelsPerUnit;
attachment.RegionOffsetX = offset.x;
attachment.RegionOffsetY = offset.y;
attachment.RegionOffsetY = offset.y;
// START: ROTATION FIX
// attachment.Width = size.y;
// attachment.Height = size.x;
attachment.Width = size.y;
attachment.Height = size.x;
// END: ROTATION FIX
attachment.RegionWidth = size.x;
attachment.RegionHeight = size.y;
attachment.RegionOriginalWidth = size.x;
attachment.RegionOriginalHeight = size.y;
attachment.UpdateOffset();


Unfortunately my pivots are still totally messed up. I can't tell if it's due to how I set up my skeleton, or if it is just more bugs galore with Unity integration.


Finally, I think I have it working. I reverted all changes I was trying out, and ended up with just one line change. We'll see if it breaks anything down the line, but it is working for now I think.

//TODO: make sure this rotation thing actually works
bool rotated = false;
if (sprite.packed)
{
  rotated = sprite.packingRotation == SpritePackingRotation.Any;
}

//do some math and assign UVs and sizes
attachment.SetUVs(texRect.xMin, texRect.yMax, texRect.xMax, texRect.yMin, rotated);
attachment.RendererObject = atlasRegion;
attachment.SetColor(Color.white);
attachment.ScaleX = 1;
attachment.ScaleY = 1;
attachment.RegionOffsetX = sprite.rect.width * (0.5f - Mathf.InverseLerp(bounds.min.x, bounds.max.x, 0)) / sprite.pixelsPerUnit;
attachment.RegionOffsetY = sprite.rect.height * (0.5f - Mathf.InverseLerp(bounds.min.y, bounds.max.y, 0)) / sprite.pixelsPerUnit;

attachment.Rotation = -90; // <

---

 New line, force the attachment rotation
attachment.Width = size.x;
attachment.Height = size.y;
attachment.RegionWidth = size.x;
attachment.RegionHeight = size.y;
attachment.RegionOriginalWidth = size.x;
attachment.RegionOriginalHeight = size.y;
attachment.UpdateOffset();
a year later

Reviving this thread because I had the same rotating issue, but I fixed it with adding a "SetUVsManually()" function in the attachment code and manually set all 8 values to the clockwise orientation of 1s and 0s. But none of the suggestions here have helped fix the fact that my sprite is still half a unit too low, for no apparent reason. The pivot is centered.

EDIT: Okay, so it seems like the attachment never receives the offsets from the JSON file that the original atlas-based attachment was set to (i.e. the attachment that I'm replacing with this sprite). There must be a way to find that though, right? Even though I don't see any vector2 values in the "Attachment" class.

None of the spine-csharp classes use Unity classes and types.
spine-csharp is shared code across all C# runtimes. Not just Unity.

I'm currently working on Attachment utilities. https://gist.github.com/pharan/d3597424698a47925ca34f3e0e7cebcf
To more-or-less complete the mix-and-match workflow story. Most likely, SpriteAttacher sample code module will be phased out.

Ideally, we could let Unity handle all of the packing at runtime but several parts of its API aren't being friendly towards that end.

But...
slot.Attachment = sprite.ToRegionAttachment(whatever overload);
or
skin.Add(slotIndex, "skin placeholder name", sprite.ToRegionAttachment(whateveroverload));
is usable.

Note that a bone points in its X-axis.
This means any images that you intend to attach to a bone at runtime should be positioned pointing to the right if you want them to point in the same direction as the bone.
I haven't noticed rotation problems using the code linked in gist, but the packing settings did have to be full rect to match the libGDX scheme.
Also see the second file that contains sample usage code.

6 days later