override public void MakePixelPerfect ()
{
Vector3 pos = cachedTransform.localPosition;
pos.x = Mathf.RoundToInt(pos.x);
pos.y = Mathf.RoundToInt(pos.y);
pos.z = Mathf.RoundToInt(pos.z);
cachedTransform.localPosition = pos;
Vector3 scale = cachedTransform.localScale;
scale.x = Mathf.RoundToInt(scale.x * 0.5f) << 1;
scale.y = Mathf.RoundToInt(scale.y * 0.5f) << 1;
scale.z = 1f;
cachedTransform.localScale = scale;
}
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.