0
\$\begingroup\$

I don't get how units and pixels work in Unity. For instance:

enter image description here

Here I have a camera with size 5. This means that there are 5 units from the center of the camera to either the top or bottom border. This means too that the total height of the camera are 10 units.

At the same time we have a "Display 1" set to 1920x1080. If the height of the screen in pixels is 1080, and there are 10 units, this would mean that every unity will be 108 pixels, right?

On the other hand, if I set the resolution of "Display 1" to 2560x1440, this would mean that every unit would draw 144 pixels, right?

Now, I have my sprite, a 35x37 pixels image.

enter image description here

Since I want my game to be a pixel art, I want the pixels to be more prominent. To do this, I would like to upscale it 4 times, meaning that instead of 35x37, I want to draw 140x148 pixels, right?

But if I go to the settings of my sprite, I find the following settings:

enter image description here

There is a field calles "pixels per unit". Which means that I have to manually the calculation between the resolution of my display and the size of my camera. So in this case set the "Pixels per unit" to 108.

But then, if I want to allow to have different resolutions in my game, say 1440p, this means that the "Pixels per unit" for my sprite must be 144, instead of 108. Since this setting is not automatic, and cannot be changed on runtime (I think), does this mean that I have to duplicate the same sprite and set every file with different PPU, depending on all the resolutions I want to support, and then in runtime select the appropiate sprite? Because that doesn't seem right.

Is there some concept I am not properly grasping about Units and Pixels?

\$\endgroup\$
2
\$\begingroup\$

Generally you want to keep your Pixels per Unit setting constant for a set of assets you use together. It's the conversion factor between the texture resolution and the coordinate space of your gameplay logic.

For example, if you're making a tile-based game with 32x32 tiles, a PPU of 32 would make good sense. Then it's easy to write say a dash move that travels 3 tiles: it moves 3 units in world space. If you later go and make an "HD" version of your game with 64x64 tiles, you can replace the assets with PPU 64 versions, and none of your gameplay logic has to change, because the logical coordinate system is still the same: 1 unit = 1 tile.

To adapt to different display sizes, the main thing you want to change is your camera.

Let's start with your 1920 x 1080 example with camera size 5, and call that our baseline. As you worked out, that means each unit of world space maps to 108 display pixels. To draw the character at a 4x scale, 140x148 pixels, then it needs to be 1.370370... world units tall. That's a PPU of 27.

Okay, now let's lock-in that PPU, and use it for all our assets, so everything has the same degree of "chunkiness" to its pixels for stylistic consistency, at a constant 4x display-pixel-to-source-texel ratio, a nice integer that helps us avoid rounding artifacts.

Now if we display on a 2560 x 1440 monitor without changing anything, our formerly 148-pixel-tall character is now drawn 197.333 pixels tall, a 5.33333 pixel-to-texel ratio, and that trailing decimal is going to cause unsightly distortions.

But we don't want to change the logical size of all our game content by changing the PPU - then we have to re-calibrate all the distances, velocities, and forces used in our gameplay scripts, so it would be a terrible mess.

So we change the camera. 5.3333 is pretty close to 5, so let's see what happens when we adjust our camera cropping to make our pixel-to-texel ratio that nice integer:

5 pixels per texel = 1440 display pixels of screen height / (camera size * 2 * 27 PPU)

Rearranging:

camera size = 1440 display pixels of screen height / (5 pixels per texel * 2 * 27 PPU)
            = 5.333333...

Running the math with these numbers, we get a camera size of 5.333333. Increase your camera size to that value, and boom, we're back to a nice neat integer pixel-to-texel ratio, without changing any of our texture assets or gameplay scripts.

This means that the player on the 1440 screen sees slightly more area than the player on the 1920 x 1080 version, just because of how integer division works when we want to display whole, non-fractional pixels.

For many games, a 6.667% change in the display area is trivial and won't alter gameplay, so we can ship with as simple a solution as this.

For other games, seeing that extra 0.6 of a world unit is a problem: it breaks the intended framing of the level, or lets the player glimpse things they shouldn't, like a secret that was supposed to be hidden juuuust off-screen. For cases like that, there are two main things you can do:

  1. Add letterboxing or a frame to keep the cropped view of your gameplay the same (on mobile games, this is often a great place to stick on-screen controls or stat displays)

  2. Include an alternative set of assets that are painted at a different resolution and use a different PPU, as described in this article.

    For this example, you'd make an alternate set of assets with a PPU of 36 instead of 27, to match the 4/3 ratio between 1440 and 1080, so you can display it at the same 4 display-pixels-per-source-texel as your 1080p version. Your alternate character sprite would be 49 texels tall, so it still boils down to the same logical size in your game, and no gameplay logic needs to change.

    You don't need to create new assets for every screen size, just ones that force you into a fractional scale that you can't solve with camera sizing/framing. So for instance, once you have these alternate assets for 1440p, you can support 720p with the very same setup, just at 2x scale instead of 4x.

But again, many games won't need to go to those lengths. If you design your game such that a ~6% change in the view area doesn't ruin the gameplay, or find an art style that lets you frame it in a way that's visually pleasing, then you can get by without the complexity of full asset swaps.

See also this previous answer where I look at this from another angle, reviewing options for scaling a game up from 720p to 1080p.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer. I'm going to read it very slowly first. Also, do you know about the "pixel perfect camera" component? Maybe that could help me to solve this issues? \$\endgroup\$ – Enrique Moreno Tent Apr 26 at 23:52
  • \$\begingroup\$ It does the same calculation I demonstrated above, if you don't want to do the math yourself. \$\endgroup\$ – DMGregory Apr 26 at 23:54

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.