Author Topic: MakePixelPerfect on SlicedSprites  (Read 2647 times)

QuantumMechanic

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
MakePixelPerfect on SlicedSprites
« on: April 10, 2013, 09:59:16 PM »
  1.         override public void MakePixelPerfect ()
  2.         {
  3.                 Vector3 pos = cachedTransform.localPosition;
  4.                 pos.x = Mathf.RoundToInt(pos.x);
  5.                 pos.y = Mathf.RoundToInt(pos.y);
  6.                 pos.z = Mathf.RoundToInt(pos.z);
  7.                 cachedTransform.localPosition = pos;
  8.  
  9.                 Vector3 scale = cachedTransform.localScale;
  10.                 scale.x = Mathf.RoundToInt(scale.x * 0.5f) << 1;
  11.                 scale.y = Mathf.RoundToInt(scale.y * 0.5f) << 1;
  12.                 scale.z = 1f;
  13.                 cachedTransform.localScale = scale;
  14.         }
  15.  

I don't understand the intention behind the way MakePixelPerfect calculates the scale of a sliced sprite.  It appears to be trying to ensure that the sliced sprite has an even scale.  Our game dynamically scales a sliced sprite from a scale of 1,10,1 to a scale of 30,10,1.  To make sure that the sprite looks clean, we calculate the scale and then apply MakePixelPerfect.  This gives a somewhat unexpected result.

Looking at the x component only, since the other components stay constant.

For an x scale of 1:
the x value is halfed making it 0.5.
then Mathf.RoundToInt rounds it to 0 (values exactly halfway between two integers are rounded to the nearest even integer). 
Then the 0 is shifted left by 1. 
Resulting in 0

This generates a LogError -- Scale of 0 is invalid! Zero cannot be divided by, which causes problems. Use a small value instead, such as 0.01

for a x scale of 3:
the x value is halfed making it 1.5.
then Mathf.RoundToInt rounds it to 2 (values exactly halfway between two integers are rounded to the nearest even integer). 
Then the 2 is shifted left by 1. 
Resulting in 4

This creates a sprite that is one pixel wider than the original scale requested.

Its possible I am not understanding an underlying assumption for sliced sprites.  Can you clarify whether this is intended behavior?  My initial expectation is that it would have done something like:

scale.x = Mathf.Floor(scale.x + 0.5f);  // round scale to the nearest hole number, if scale is exactly half -- round upward.