0
\$\begingroup\$

I created a test image that is 60 x 60 px, which has a 1px border. I then drop that into Unity as a UI sprite image set to the same size, however the 1px border on a few sides can appear to be thicker, and this ruins the look I am going for especially when there are multiple of them.

I've tested in the editor and creating builds (testing resolutions), and the same issue in all cases.

It's easier to explain this with images.

The left screen shot is the actual size of the image in the game view. The zoomed in image is another case where the borders change thickness, but zoomed in to make it more clearer.

I've tried various settings, always the same issue.

How can I get the image to appear exactly as it should with no changes to the borders?

\$\endgroup\$
  • 1
    \$\begingroup\$ I think you can solve this by using pixel-perfect mode (or using no compression). I'd have to check it on Unity to be sure. \$\endgroup\$ – John Hamilton Oct 9 '17 at 10:52
  • 1
    \$\begingroup\$ @JohnHamilton Pixel perfect checkbox on the canvas helped fix it along with some info from the solution posted by DMGregory. Not sure how I missed that checkbox, thanks though. \$\endgroup\$ – JacketPotatoeFan Oct 9 '17 at 11:11
2
\$\begingroup\$

There are a couple of points you need to take into account to solve this.

First you'll want to switch your sprite's Mesh Mode in its texture import settings to Full Rect so you can enable 9-slice scaling on it as described in the Unity docs.

This lets you select either the Sliced or Tiled modes on your Sprite or Image components, which will ensure borders of your sprite stay the same thickness in the game world/canvas when the sprite is enlarged - they'll be spaced out or tiled instead of stretched to fit.

For a non-UI sprite, the size of the border in actual display pixels will depend on how your camera sees it. This includes your pixels per unit setting, the size of your orthographic camera, and the resolution of the display viewport. You can work out the result using these formulas:

world thickness = (1 pixel of texture) ÷ (pixels per unit)

vertical screen fraction = (world thickness) ÷ (camera height * 2)

display pixels = (vertical screen fraction) * (pixel height of display viewport)

(For perspective cameras you also need to factor in the depth of the sprite from the camera)

You'll want to carefully choose your pixel per unit and camera settings to keep this at an integer value. Otherwise you can get one border drawn thicker than the other if one border rounds the fraction differently.

For an Image component displayed as part of your UI, this is a bit easier to manage. Set up your Canvas with a CanvasScaler set to Constant Pixel Size, with the Reference Pixels per Unit value the same as the one you used to import your sprites, or an integer multiple of it if you want to upscale the art (Don't forget to switch your textures to Point filtering if you're upscaling pixel art).

Then enable the Pixel Perfect box in the Canvas component, which turns off anti-aliasing on UI so you get exactly the pixels of your sprite.

\$\endgroup\$
  • 1
    \$\begingroup\$ Nice. Some really useful info here that I had no idea about. With some of the info you provided and turning on pixel perfect mode (thanks to the comment by @JohnHamilton) on the canvas, the image (part of the UI) border is now 1px all the way around. Thanks \$\endgroup\$ – JacketPotatoeFan Oct 9 '17 at 11:17
0
\$\begingroup\$

In the settings for the sprite use Filter Mode of "point" instead of Bilinear.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.