# Unity2D: Automatic scaling of camera and sprites

I'm working on a point-and-click adventure game using Unity2D for mobile devices and possible PCs and I'm trying to wrap my head around supporting devices with different screen sizes and aspect ratios.

My background images are high quality and quite large (let's say 4096 x 3072), and I'm trying to scale them down to at least fit into the viewport. However, try as I may, the scaled image always seems to end up either too large for the viewport or much too small.

I'm using an ortographic camera that automatically adjusts its size based on the current screen size using the formula (Screen.height / 2f) / 100.

To scale down my Sprites, I'm using the following code:

float scaleY = background.renderer.bounds.size.y / Globals.camera.rect.height;
float inverseY = 1/scaleY;

background.transform.localScale = new Vector3 (inverseY , inverseY);


This results in a background that is way too small to work with. Removing the inverse only serves to make the background massive.

Help?

I think the orthographic size of your camera should depend on the size of your sprites (and possibly on the aspect ratio of the screen), but not on the size of the screen, so that you don't need to apply any scaling to your sprites.

As a reminder, the orthographic size of the camera is the half-height of the area (in Unity world) which will be rendered on the device's screen.

For instance, if your background is 4096x3072 and you set an orthographic size of (3072 / 2) / 100 = 15.36, then your background will cover the whole height of the screen, and for the width:

• on a narrow screen you won't see the full width of the background (it will be cropped on left and right)
• on a wide screen you'll have blank are on the left & right of the background (that is pillarboxing)

If you want your background to be always fully visible and be as big as possible, then you need to change the orthographic size on narrow screens to have letterboxing (blank area on top & bottom), as explained in this blog post:

This is achieved with the following script (which should be attached to your camera object), where targetAspect should be filled with the desired aspect ratio of your game area (i.e 4096 / 3072 in your case):

using UnityEngine;
using System.Collections;

public class AspectRatioScript : MonoBehaviour {

public float targetAspect;

void Start ()
{
float windowAspect = (float)Screen.width / (float)Screen.height;
float scaleHeight = windowAspect / targetAspect;
Camera camera = GetComponent<Camera>();

if (scaleHeight < 1.0f)
{
camera.orthographicSize = camera.orthographicSize / scaleHeight;
}
}
}

• So in this case, I would be "zooming" the camera in and out, so the speak, to fit the smaller devices? This would make a lot more sense, especially since I have other GameObjects on screen that cannot move position when scaled. – Simon Cutajar Feb 25 '15 at 21:37
• Yes, the idea is to define your camera size with respect to Unity world's abstract units, without worrying about the actual size of the screen on which it will be rendered. Unity is responsible for making the appropriate "zooming", when rendering, to fit the screen height (the script makes just a small fix to fit width instead of height on narrow screens) – sdabet Feb 25 '15 at 21:42
• Hmm, I've added this to my scene, but I still get a massive background image. I suspect the issue is because I'm loading the Sprites dynamically through an XML file, but since I'm still rather new to Unity, I'm not exactly sure how to go about this. – Simon Cutajar Feb 25 '15 at 21:48
• Your background is massive compared to what? – sdabet Feb 26 '15 at 6:58
• Basically, with the code you provided, I expect that when I dynamically create a sprite and add it to the scene, it should automatically fit into the camera's viewport. Presumably, because the background is quite large, I end up seeing a really tiny portion of it in the actual viewport, which is why I mention scaling as an option :/ – Simon Cutajar Feb 26 '15 at 7:10

Depending on exactly what you are trying to achieve, I might recommend not scaling anything (either the camera or your sprites) and instead just worry about the differing aspect ratios (eg. moving things to the edges of wider screens). Things will scale to fill the screen automatically; the graphics won't be pixel-perfect anymore, but with the high-resolution displays these days, that may not matter.