SysOp

Hello!

On the previous engine we used, Haxe based, I hacked my way in and did it, but I was wondering if there's a proper solution for Unity.

In our game, we have characters which gets damaged. I need them to change body parts, but since these parts are a lot and there's lots of characters, I need to do that via code.



Sprite dimensions won't change. Is just a sprite replacement. Is there a way to grab a sprite from "resources/" folder and use that one, for the damaged head instead? Thanks in advance. 8)
Avatar
SysOp
  • Postovi: 30

Harald

Yes, there is a proper built-in solution available in spine-unity. Please check out the example scenes Spine Examples/Other Examples/Mix and Match and Mix and Match Equip that come with the spine-unity package. These show how you can switch out attachments with Unity Sprites.

You can also have a look at the Runtime Repacking section in the spine-unity documentation pages here, which is also used in the above example scenes:
spine-unity Runtime Documentation: Combining Skins
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

Hey, thanks a lot for the answer. I followed your information and managed to do what I wanted.

However, I bumped into a scale issue:



The circled one, uses the very same image as the source, but for some reason, is smaller. What would be the cause for this? Thanks a lot for your time and for helping so much 8)
Avatar
SysOp
  • Postovi: 30

parth16parikh

I have been trying to do the same thing and encountered the same problem. In my case some are getting bigger and some are getting smaller. Did you get any solution to that?
parth16parikh
  • Postovi: 9

SysOp

I have been trying to do the same thing and encountered the same problem. In my case some are getting bigger and some are getting smaller. Did you get any solution to that?
Same issues here and sadly, no solution that I could find. I would be editing this post if I find something.
Avatar
SysOp
  • Postovi: 30

Harald

We are sorry for the troubles! Could you please create a minimal Unity package that still shows the problem, and send it as a zip package to contact@esotericsoftware.com, then we can have a look at what's going wrong.

Edit: @parth16parikh @SysOp After sending a zip package, please post here on the forum, so that only one of you two needs to create and send a reproduction package.

Remark: The discussion from this thread will be continued here.
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

Done, sent to that address :)

Click on the button to replace it:



There's no custom code, uses scripts from Mix and Match examples.

Thanks for the amazing support :love:
Avatar
SysOp
  • Postovi: 30

parth16parikh

Hi @Harald,

I have also sent email to the email which you said.

You can just open the Test scene and hit play. As you click on the play button, green character will turn blue. You will be able to notice problem in that.

Just for further updates, Are you going to update me on this thread or you will be updating me on email?

Thank you for the quick support.
parth16parikh
  • Postovi: 9

Nate

Thanks! Harald will check it out as soon as he can. We normally keep the discussion on the forum when possible and respond to the email only to say we've replied on the forum.
Avatar
Nate

Nate
  • Postovi: 11791

Harald

@SysOp
Thanks for sending the reproduction package. Unfortunately after loading the unitypackage there is a missing script on the Main Camera GameObject, and nothing happens when clicking the buttons. In general we prefer zip packages of the project (without the Library dir) to unitypackages as this saves us some time. Anyway, since Parikh also sent us a package there is no need to send an updated package.

@parth16parikh
Thanks for sending the reproduction package, we received everything and can see the issue occurring in your project.
We will get back to you here on the forum once we've figured out what's going wrong.

---

@parth16parikh
After having a detailed look at your reproduction project, the problem turned out to be different sizes of the image (so not a bug in spine-unity):
images-not-equal-size.png

The blue foot is of size 231 x 207 (tightly clipped without borders) while the green one is larger, size 263 x 263 with a transparent border around it. At least Spine shows this size at the green one in the atlas.txt file and upon atlas-unpacking, the resulting image is of this size. As you are saying they are of equal size: did you clamp them somewhere along your workflow perhaps?

---

@SysOp
I just had a detailled look at your reproduction project. The problem is as follows: Your atlas has been exported with Strip Whitespace X/Y set to a non-zero border (see the documentation here). Now in the EquipSystemExample class, templateAttachment.GetRemappedClone() is called with default parameter useOriginalRegionSize = false here. So you need to call GetRemappedClone() with the parameter useOriginalRegionSize explicitly specified as true as follows:
attachment = templateAttachment.GetRemappedClone(asset.sprite, sourceMaterial, premultiplyAlpha: this.applyPMA, useOriginalRegionSize : true);
Another solution would be to disable whitespace stripping upon atlas texture export.

I will investigate (most likely tomorrow) whether behaviour of GetRemappedClone() with useOriginalRegionSize set to false should behave differently than it does right now. I will get back to you once I've come up with an answer.
Nemaš dopuštenje za pregledavanje privit(a)ka dodan(og)ih postu.
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

That, indeed, solves it!



I suspected it had something to do with white space stripping as I had same issue on previous engine, I even tested that out, but perhaps got myself confused.

Thanks a lot for checking this out, customization, here we go! :heart:
Avatar
SysOp
  • Postovi: 30

Harald

Thanks for your kind words, very glad it helped! :)
Harald je napisao/la:I will investigate (most likely tomorrow) whether behaviour of GetRemappedClone() with useOriginalRegionSize set to false should behave differently than it does right now. I will get back to you once I've come up with an answer.
I will have a look at this right now and will let you know if we can provide an improvement in this regard as well.
Avatar
Harald

Harri
  • Postovi: 3914

parth16parikh

Hi @Harald,

Yea size of the image in atlas is 263 x 263. So we tried to increase the size of the blue foot image to 263x263. When we did that we get this error "negative source coordinates".

Actual size of the green foot in the spine software is 231x207. When we export it from spine, then it will show 263x263 in atlas file. That is the reason why blue foot size is 231x207.

Also one more update, when we added one pixel black line in 231x207 size blue foot image then it worked properly. I dont know where exactly the problems is. Let me know if you have any explanation.
parth16parikh
  • Postovi: 9

Harald

parth16parikh je napisao/la:Yea size of the image in atlas is 263 x 263. So we tried to increase the size of the blue foot image to 263x263. When we did that we get this error "negative source coordinates".
Could you please describe exactly what you did, and where this exception or error occurred? Could you share some screenshots of the Texture and Sprite import settings?

A side note: I noticed that your foot attachment is a MeshAttachment and not a RegionAttachment. MeshAttachments are more limited in regard to remapping, so a working setup for RegionAttachments may produce incorrect results on MeshAttachments. This is mostly due to the Mesh vertex positions, which cannot be expanded or contracted as RegionAttachments vertices. Mesh vertices need to stay as they are, only uv coords are modified to map the texture differently.
parth16parikh je napisao/la:Actual size of the green foot in the spine software is 231x207. When we export it from spine, then it will show 263x263 in atlas file. That is the reason why blue foot size is 231x207.
It is strange that the output image in the atlas is larger than the input image. Could you please send us your Spine project files, so that we can have a look at it? Could you please also post a screenshot of your Texture Packer Settings used when exporting the atlas from Spine?
parth16parikh je napisao/la:Also one more update, when we added one pixel black line in 231x207 size blue foot image then it worked properly. I dont know where exactly the problems is. Let me know if you have any explanation.
Most likely the problem is that the Sprite Mesh Type import setting is set to Tight instead of Full Rect, which will additionally clamp transparent borders. Unfortunately tight packing is not yet fully supported in spine-unity. Please try setting it to Full Rect for now.

I have created an issue ticket here to cover Mesh Type Tight:
https://github.com/EsotericSoftware/spine-runtimes/issues/1884
Unfortunately it will most likely take some time until we get to implement this issue ticket, due to many higher priority tasks.

---

Harald je napisao/la:I will investigate (most likely tomorrow) whether behaviour of GetRemappedClone() with useOriginalRegionSize set to false should behave differently than it does right now. I will get back to you once I've come up with an answer.
@SysOp
The main problem with the Sprite attachment being too small was due to the implicitly used scale not being equal to the original attachment scale, since it uses the Sprite's Pixels per Unit value (set to the default value of 100, which leads to a scale of 0.01).

We have just released some improvements regarding the behaviour when useOriginalRegionSize is set to false:
Changelog.md je napisao/la:Attachment.GetRemappedClone(Sprite) method now provides an additional optional parameter useOriginalRegionScale. When set to true, the replaced attachment's scale is used instead of the Sprite's Pixel per Unity setting, allowing for more consistent scaling. Note: When remapping Sprites, be sure to set the Sprite's Mesh Type to Full Rect and not Tight, otherwise the scale will be wrong.
So calling GetRemappedClone(.., useOriginalRegionScale : true) should improve the situation for many cases where you want to maintain the replaced attachment's scale instead of using a specific Sprite scale.
New 3.8 and 4.0-beta unitypackages are available for download here as usual:
Spine Unity Download
Note that only has an effect on RegionAttachments, not on MeshAttachments. Please let us know if this works for you as well and whether it improves the situation.

Also beware to set all Sprite's Mesh Type to Full Rect and not Tight as described in the changelog, as this causes improper scale when using the head_robot_test: when the Sprite is set to Full Rect it maps correctly, when set to Tight it is incorrectly stretched vertically.
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

Thanks for the explanation and for the hard work mate. Backing up this project was one of the best decisions I ever made <3

EDIT: When optimizing the skin (by pressing Done), my character looks like this (main texture looks like gray boxes):



And in the console, I get dozens of:
Graphics.CopyTexture can only copy memory with the same size (src=26240 bytes dst=6560 bytes), maybe the size (src=163 * 160 dst=41 * 40) or format (src=RGBA Compressed DXT5 UNorm dst=RGBA8 UNorm) are not compatible
What might be the cause of this?
Avatar
SysOp
  • Postovi: 30

Harald

Thanks for your kind words. 8)

Regarding the issue with repacking:
SysOp je napisao/la:src=RGBA Compressed DXT5 UNorm
Most likely it's the DXT5 compressed source texture which cannot be read, please change the texture import settings (for all target platforms) from Compressed to an uncompressed format.

You can also have a look at the list that reads "Important Note: If repacking fails [..]" in section Runtime Repacking on the spine-unity documentation pages here:
spine-unity Runtime Documentation: Combining Skins
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

Disabling compression and enabling read/write did the trick! Huge thanks again! <3

EDIT: Deeply sorry to again bring out issues, but after repacking, I'm losing a material.

Here's the ones I use:



After repacking I lose one:



I read the documentation and SpineBoy example uses a single material. I tried to do something like:
int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("-Additive") };

repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", sourceMaterial, out runtimeMaterial, out runtimeAtlas, additionalTexturePropertyIDsToCopy: additionalTexturePropertyIDsToCopy); // Pack all the items in the skin.
... to copy that additive material, but doesn't work. I'm obviously doing something wrong.
Avatar
SysOp
  • Postovi: 30

Harald

SysOp je napisao/la:Disabling compression and enabling read/write did the trick! Huge thanks again! <3
Very glad to hear that! 8)
SysOp je napisao/la:EDIT: Deeply sorry to again bring out issues, but after repacking, I'm losing a material.
No need to apologize. The main purpose of the repacking methods is to reduce drawcalls by using a single texture and material. Unfortunately, packing to two separate output materials is not supported by these methods. I'm afraid you will have to call GetRepackedSkin() or GetRepackedAttachments() once for each material that you want to keep, as either of these methods creates only a single output material. So you could either create two lists of attachments and use GetRepackedAttachments, or create two separate Skins, add the respective attachments to one of the two skins and call GetRepackedSkin() for both skins.

In general you could have a look if you would be saving draw calls at all by repacking to multiple materials. If you would have the same number of submeshes and materials before as after repacking, then you can save the repacking step. You will not benefit much (or at all) if you have two drawcalls with one repacked texture, compared to two drawcalls with two textures.
SysOp je napisao/la:
int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("-Additive") };
The additionalTexturePropertyIDsToCopy parameter is only for additional texture maps at the same material, e.g. when you have a material with diffuse, normal and emissive textures that all shall be repacked the same way in one go.
Avatar
Harald

Harri
  • Postovi: 3914

SysOp

You will not benefit much (or at all) if you have two drawcalls with one repacked texture, compared to two drawcalls with two textures.
Ah, okay then. Yeah, I'm only using 4 customizable characters max, it won't affect the performance at all. Since this pretty much done, I'm marking this as solved. Thanks again! :heart:
Avatar
SysOp
  • Postovi: 30

Harald

You're welcome, glad it helped! :)
Avatar
Harald

Harri
  • Postovi: 3914

parth16parikh

@Harald
Could you please describe exactly what you did, and where this exception or error occurred? Could you share some screenshots of the Texture and Sprite import settings?
So actual image size of the green foot is 231x207. But in atlas it shows 263x263. So I simply opened 231x207 and added transparency on all 4 sides to make 263X263. Now there 2 cases from here,

1. If I add transparency and load image from the Resources then it works perfectly.
2. If I add transparency to the image. Make it 263x263 and now I try to load it through the persistence data path then it throws below error.
Graphics.CopyTexture called with negative source coordinate (x on cpu 0 , on gpu 0 ; y on cpu -53, on gpu 0) .
UnityEngine.Graphics:CopyTexture(Texture, Int32, Int32, Int32, Int32, Int32, Int32, Texture, Int32, Int32, Int32, Int32)
Spine.Unity.AttachmentTools.AtlasUtilities:CopyTexture(Texture2D, Rect, Texture2D) (at Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs:601)
Spine.Unity.AttachmentTools.AtlasUtilities:ToTexture(AtlasRegion, TextureFormat, Boolean, Int32, Boolean, Boolean) (at Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs:543)
Spine.Unity.AttachmentTools.AtlasUtilities:GetRepackedSkin(Skin, String, Shader, Material&, Texture2D&, Int32, Int32, TextureFormat, Boolean, Material, Boolean, Boolean, Int32[], Texture2D[], TextureFormat[], Boolean[]) (at Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs:417)
Spine.Unity.AttachmentTools.AtlasUtilities:GetRepackedSkin(Skin, String, Material, Material&, Texture2D&, Int32, Int32, TextureFormat, Boolean, Boolean, Boolean, Int32[], Texture2D[], TextureFormat[], Boolean[]) (at Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs:354)
<Start>d__10:MoveNext() (at Assets/Texture Change Test/ChangeCharacter.cs:87)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
Should I send another project in which I load images from persistent data path? That is actually what I want to do. I dont want to load it from Resources. I thought loading it from Resources will reproduce same scenario. Apologies for wasting some time.

Let me know if I need to send you another project which loads images from persistent data path or not.
parth16parikh
  • Postovi: 9

Harald

Thanks for posting the additional info.
parth16parikh je napisao/la:Let me know if I need to send you another project which loads images from persistent data path or not.
Yes, please send us a Unity project using your desired persistent data path setup. Please keep it as minimal as possible, e.g. replace only the single problematic attachment instead of replacing 7 attachments where the 5th one fails. This saves us a lot of time.

Please also send us your Spine project, so that we can try to reproduce why the image is padded from 231x207 to 263x263.
Avatar
Harald

Harri
  • Postovi: 3914

parth16parikh

Hi @Harald,

I tried somethings and found solution ultimately.

So we were trying to replace total 8 images in the character. 4 of them were attached to Mesh Attachment and 4 of them were attached to Image Attachment.

So for 4 images which are attached to Mesh Attachment needs following requirement,
1. Image loaded from the persistent data path has to match atlas.txt size.
2. After loading texture, Sprite which is created runtime needs to be Full Rect Mesh Type.

after that it worked perfectly for Mesh Attachments.

So for 4 images which are attached to Image Attachment needs following requirement,
1. Image loaded from persistent data path has to match the original size of the image. It should not be the size which is defined in atlas.txt.
2. After loading texture, Sprite which is created runtime needs to be Full Rect Mesh Type.

I can send you this project which is working completely if you want.

I wanted to ask performance impact of changing and repacking images runtime. How heavy it is? Once it is done, does it affect animation?
parth16parikh
  • Postovi: 9

Harald

Thanks for the additional info.
parth16parikh je napisao/la:So for 4 images which are attached to Mesh Attachment needs following requirement,
1. Image loaded from the persistent data path has to match atlas.txt size.
2. After loading texture, Sprite which is created runtime needs to be Full Rect Mesh Type.
Admittedly, this current behaviour is rather unintuitive. We will have a look if we can provide either an additional method parameter or change default behaviour in spine-unity 4.0 and newer versions to compensate whitespace stripping on MeshAttachments as well.
parth16parikh je napisao/la:I can send you this project which is working completely if you want.
Thanks for offering, currently we don't need it. We will let you know when we require a test project if we cannot reproduce the described behaviour.
parth16parikh je napisao/la:I wanted to ask performance impact of changing and repacking images runtime. How heavy it is? Once it is done, does it affect animation?
Repacking skins is a very costly operation performance wise, as uploading a texture to the GPU is an expensive operation. If possible, you should always perform any repacking at non-crucial times (e.g. when already loading a level, or when inside a character customization menu). It will however save you some drawcalls, so if can move it to non-crucial moments of gameplay, it's most likely well worth the cost. We cannot provide any precise values, as this heavily depends on your scene and character setup and on the target platform. If your character setup does not require many drawcalls before repacking, you might as well be better off not repacking the skins at all.

---

Harald je napisao/la:Admittedly, this current behaviour is rather unintuitive. We will have a look if we can provide either an additional method parameter or change default behaviour in spine-unity 4.0 and newer versions to compensate whitespace stripping on MeshAttachments as well.
I just had a look at your previous reproduction project again, the problem here is that the .atlas.txt file states size 263x263 for both size and original size ("orig" in the file), not stating the proper original size as you said is 231x207. As requested before, could you please now send us your problematic Spine project (not the Unity project) where the actual image size of the green foot is 231x207 and in the output atlas it becomes 263x263?
Avatar
Harald

Harri
  • Postovi: 3914

parth16parikh

@Harald I have sent you spine file from e-mail.

It seems like you are correct. Original file has to be 263X263. Artist might be in some confusion. I am also going to verify it now.
parth16parikh
  • Postovi: 9


Natrag na Unity