Author Topic: Help finding the right scale for an icon inside a backgorund sprite [SOLVED]  (Read 3543 times)

vexe

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 153
    • View Profile
Hello, In my inventory system, an item could take more than one slot, 2x2, 2x3, 3x3, etc. Each item has a texture - I don't care about the texture size (for a 2x2 item, the texture size doesn't have to be like, 256x256 or 128x128, but it would be better if it was)

Since I'm using NGUI, the item slot is actually a button, with a background, an icon (both sprites) and a label. I instantiate the slots, by using a Slot prefab, which has a script that stores the Slot size, for now I'm using 50. There's also a spaceBetweenSlots variable, which is 5.

So if I had a 2x2 item, its background would be of size 105x105, I scale the background to that size.

But the problem is, the item icon. I can't seem to know how to scale the icon, for it to fit perfectly inside the background. Take a look at the attached pictures.

Now the RedHerb fits, because its size is 594x601 and I'm scaling it by 100x100x1, but the gun is 640x453, if I scale it by the same scale as the Herb, you would get the results above.

Now the question is, how can I scale the icon to perfectly sit inside the background?


My attempts:
I came up with an idea of finding the difference between the icon's and the background's size, I keep scaling down the icon till there's a low dif between the two sizes. But NGUI is giving me a hard time of doing anything -_-

For my idea to work I just need the icon's and the background's size. I searched and found NGUIMath.CalculateAbsoluteWidgetsBounds, I'm not sure how to use it, it asks for a transform, and returns a Bounds, so I gave my background's, it got me back a bound with size of 0.2x0.2, did the same for the icon it gave me back a size of 0.0x0.0 lol O_O what is that?!

I tried background.relativeSize, I got back a V3 of (50,50,1) - The forums says to Scale that by background.cachedTransform.relativeSize, to get the size in pixles, so I did:

  1.  background.relativeSize.Scale(background.cachedTransform.localScale);

Is that correct? is that how to scale two vectors? - I got back a V2 of (1.0, 1.0) :D

Any help would be much appreciated, thanks a lot.
« Last Edit: August 14, 2013, 09:29:46 AM by vexe »

vexe

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 153
    • View Profile
Re: Help finding the right scale for an icon inside a backgorund sprite
« Reply #1 on: August 14, 2013, 03:40:03 AM »
Just to recap: The background is scaled 105,105,1 the gun is 100,100,1 - that gives the result ^. However, if manually change the gun scale down to 85,75,1 it fits perfectly. My whole journey is to figure out a formula to give me back that new scale I have to apply to the gun.

Chulup

  • Guest
Re: Help finding the right scale for an icon inside a backgorund sprite
« Reply #2 on: August 14, 2013, 06:38:05 AM »
May be I get it wrong but seems I wrote a script that should help. It helps to keep aspect ratio of sprite while scaling it to target size. It also scales BoxCollider.
  1. using UnityEngine;
  2. using System.Collections;
  3. using Common;
  4.  
  5. namespace Common.UI
  6. {
  7.     [ExecuteInEditMode]
  8.     public class ScaleKeepRatio : MonoBehaviour
  9.     {
  10.         public Vector2 targetSize = new Vector2(100, 100);
  11.         public UISprite sprite;
  12.         public BoxCollider boxCollider;
  13.  
  14.         private Vector2 _oldSize = new Vector2();
  15.         private Vector2 _oldRealSize = new Vector2();
  16.  
  17.         // Use this for initialization
  18.         private void Start()
  19.         {
  20.             sprite = GetComponent<UISprite>();
  21.             boxCollider = GetComponent<BoxCollider>();
  22.         }
  23.  
  24.         // Update is called once per frame
  25.         private void Update()
  26.         {
  27.             //var realSize = Vector2.Scale(sprite.relativeSize, sprite.transform.localScale);
  28.             //if (CommonTools.Vector2Equal(realSize, _oldRealSize) &&
  29.             if (Vector2Equal(sprite.transform.localScale, _oldRealSize) &&
  30.                 Vector2Equal(targetSize, _oldSize)) return;
  31.             Rescale();
  32.             _oldSize.Set(targetSize.x, targetSize.y);
  33.             _oldRealSize.Set(sprite.transform.localScale.x, sprite.transform.localScale.y);
  34.         }
  35.  
  36.         private void Rescale()
  37.         {
  38.             var image = sprite.GetAtlasSprite();
  39.             var imX = image.inner.width;
  40.             var imY = image.inner.height;
  41.             var imAspectRatio = imX / imY;
  42.             var targetAspectRatio = targetSize.x / targetSize.y;
  43.             // Compute resulting size of image scaled to fit targetSize keeping aspect ratio
  44.             float resultX, resultY;
  45.             if (imAspectRatio > targetAspectRatio)
  46.             {
  47.                 resultX = targetSize.x;
  48.                 resultY = imY * targetSize.x / imX;
  49.             }
  50.             else
  51.             {
  52.                 resultX = imX * targetSize.y / imY;
  53.                 resultY = targetSize.y;
  54.             }
  55.             // Apply resulting size to sprite
  56.             sprite.cachedTransform.localScale = new Vector3(resultX, resultY, 0);
  57.             if (boxCollider != null)
  58.                 boxCollider.size = new Vector3(targetSize.x / resultX, targetSize.y / resultY, 0);
  59.         }
  60.        
  61.         public static bool Vector2Equal(Vector2 left, Vector2 right, float precision = 0.01f)
  62.         {
  63.             var magnitude = Vector2.SqrMagnitude(left - right);
  64.             return magnitude < precision;
  65.         }
  66.     }
  67. }

vexe

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 153
    • View Profile
Re: Help finding the right scale for an icon inside a backgorund sprite
« Reply #3 on: August 14, 2013, 09:28:30 AM »
Thank you so much for being helpful! - I was actually looking for a way to calculate the a sprite's width/height, this helped me a lot:
  1. var image = sprite.GetAtlasSprite();
  2. var imX = image.inner.width;
  3. var imY = image.inner.height;
  4.  

But I actually managed to find another, much easier way to fix the problem.

Testing that code on my Herb texture, it gave back the actual size, but on my 640x453 gun texture, I actually got a 525x320 or something, which I found to be really odd. Somebody's messing with the size. So I went out and googled "Unity change texture size on import" and found this >> http://answers.unity3d.com/questions/241605/image-size-altered-upon-import.html << - So I immediately disabled that compressing option, and re-added my texture to my atlas, but again, I'm not getting the right size. That is when I knew that NGUI must have something to do with this. I went to the Atlas tool, and found out a setting called "Trim Alpha" (Remove empty spaces) - I ticked that one off and BAM! without no code or anything, the icon/sprite scaled and fitted perfectly! :))

Wish I could upvote you or something, without your texture size finding code, I wouldn't have known where to look, thanks again.
« Last Edit: August 14, 2013, 09:41:45 AM by vexe »