• Runtimes
  • [Unity] How to get images from skeleton

  • Düzenlendi
Related Discussions
...

I'm trying to get hold of the actual image for a slot so that I can let the user drag it off the character and vice versa drag a new item to the slot.
I've got the following code working for finding the slot and setting the alpha on the slot image. But how do I get the actual image so I can drag it around?:

Vector3 wp = Camera.main.ScreenToWorldPoint (Input.mousePosition);
Vector2 touchPos = new Vector2 (wp.x, wp.y);
if (boxColliderHeadGear == Physics2D.OverlapPoint (touchPos)) {
  slot = skeletonAnimation.skeleton.FindSlot ("head_gear");
  imageRegion = slot.Attachment as RegionAttachment;
  imageRegion.A = 0.7f;
  xOriginal = imageRegion.X;
  yOriginal = imageRegion.Y;
  Debug.Log ("Tapped head gear...");
}

Once you have the RegionAttachment you can get the rendererObject, which you can cast to a AtlasRegion. This gives you the UVs, whitespace stripping, rotation, etc of the texture atlas region. It also gives you the AtlasPage which has its own rendererObject which can be cast to a Unity Material:
https://github.com/EsotericSoftware/spi ... er.cs#L148

spine-unity uses a single GameObject to render the whole skeleton, which is more efficient than using a GameObject per attachment. You can probably create a new GameObject that renders the atlas region and have the user drag that around while the real attachment on the skeleton is just hidden.

OK - I got that working, sort of. I am creating a Sprite and adding it as a child GameObject, but the rect I'm getting from the atlas region is not getting the correct region from the atlas. :p

Slot slot = skeletonAnimation.skeleton.FindSlot ("head_gear");
RegionAttachment imageRegion = slot.Attachment as RegionAttachment;
imageRegion.A = 0.7f;

AtlasRegion atlasRegion = imageRegion.RendererObject as AtlasRegion;
Material material = (Material)atlasRegion.page.rendererObject;
Rect atlasRect = new Rect (atlasRegion.x, atlasRegion.y, atlasRegion.width, atlasRegion.height);
Sprite sprite = Sprite.Create (material.mainTexture as Texture2D, atlasRect, new Vector2 (0.5f, 0.5f));

GameObject spriteGameObject = new GameObject ("DragSprite");
spriteGameObject.transform.parent = skeletonAnimation.transform;
spriteGameObject.AddComponent<SpriteRenderer> ();
spriteGameObject.GetComponent<SpriteRenderer> ().sprite = sprite;

sed to use the

imageRegion.uvs;

to get the correct rect in the atlas and in that case, how do I do that?

RegionAttachment#UVs gives you the UVs for the 4 corners of the region. This has region rotation taken into account. Otherwise AtlasRegion has x, y, width, height which is the region in texels. How you use this to construct a Unity Sprite, I'm not sure. That's a Unity thing and out of Spine land. 🙂 Note you can turn off rotation in your atlas if that is easier.

Ahh - that did it! I needed to use the UV info.

Rect atlasRect = new Rect (imageRegion.uvs [RegionAttachment.X1] * atlasRegion.page.width, imageRegion.uvs [RegionAttachment.Y1] * atlasRegion.page.height, (imageRegion.uvs [RegionAttachment.X3] - imageRegion.uvs [RegionAttachment.X1]) * atlasRegion.page.width, (imageRegion.uvs [RegionAttachment.Y3] - imageRegion.uvs [RegionAttachment.Y1]) * atlasRegion.page.height);

And then I just rotate the image if needed (I'm guessing images are only ever rotated left in the atlas):

          if (atlasRegion.rotate) {
            spriteGameObject.transform.Rotate (new Vector3 (0.0f, 0.0f, 270.0f));
          }

Thanks for the help! :happy: