same visible area regardless of aspect ratio

Hi :D

How to make it so that regardless of aspect ratio the camera would show the same portion of the world?

If the whole screen could be stretched, how? If I could add a black border to the sides, how?

(Checked out how others do it so I fired up S.W.A.T. 4 which uses the Unreal Engine and checked the game with both 4:3 and 5:4 and the same could be seen and I didn't notice any stretching so there might really be better ways than those mentioned above.)

What else could one do, how?

If it's sg. with matrices then please consider that one might be a newbie with those (too).

Thanks in advance :)

Stretching could probably be achieved by modifying the Camera.aspect property, but would you really want that? It probably makes for a poor visual experience.

And black padding, isn't that also quite poor visuals?

I think most games simply use a fixed FOV (field of view) and don't care much about not showing exactly the same portion of the world.

When you set FOV on a Unity camera it represents the vertical FOV: http://unity3d.com/support/documentation/ScriptReference/Camera-fieldOfView.html

If however you want to keep the horizontal FOV fixed, try something like this:

myCam.fieldOfView = myDesiredHorizontalFov / ((float)myCam.pixelWidth / myCam.pixelHeight);

Note that this needs to run whenever the viewports change. I have not tested this code for correctness. :)

If you want to letter/pillar box then something like the below script is probably what you want. Note that it is not a complete generalised solution, it is only a demonstration. It assumes the aspect ratio you want for the viewport is 16:9.

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Camera))]
public class LetterBoxing : MonoBehaviour {

    const float NORMAL_ASPECT = 4/3f;
    const float COMPUTER_WIDE_ASPECT = 16/10f;
    const float EPSILON = 0.01f;

    void Start () 
    {
        float aspectRatio = Screen.width / ((float)Screen.height);

        if (Mathf.Abs(aspectRatio - NORMAL_ASPECT) < EPSILON)
        {
            camera.rect = new Rect(0f, 0.125f, 1f, 0.75f); // 16:9 viewport in a 4:3 screen res
        }
        else if (Mathf.Abs(aspectRatio - COMPUTER_WIDE_ASPECT) < EPSILON)
        {
            camera.rect = new Rect(0f, 0.05f, 1f, 0.9f); // 16:9 viewport in a 16:10 screen res
        }

        //  everything else is assumed to be 16:9.
    }
}

I found this helpful, but I needed a general solution, so I extended @PeterGriffin3’s solution by a bit. I thought I should share it;

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Camera))]
public class Letterboxing : MonoBehaviour 
{
	const float KEEP_ASPECT = 16/9f;
	
	void Start()
	{
		float aspectRatio = Screen.width / ((float)Screen.height);
		float percentage = 1 - (aspectRatio / KEEP_ASPECT);

		camera.rect = new Rect(0f, (percentage / 2), 1f, (1 - percentage));
	}
}

Now of course you could change the KEEP_ASPECT to anything you like.

Hey the script works just fine for me! But I need to support the ratio of 5:4 as well and I just didnt get really how you calculated the rectangles for the different ratios! It would be very kind when someone can help me out!

This is probably a little basic and I am definitely a very new programmer. but I have the problem of having to output a project to multiple devices with different aspect ratios, and this is what I am doing so far:

PS - my cameras are all positioned in world space. I figure out what Z position looks good for each aspect ratio, and then set the z for the camera, based on the aspect ratio I am running or building to.

//---------------

var ratio0403 : boolean = true; // this setting also works for 5:4 in my case

var ratio0302 : boolean = false;

var ratio1610 : boolean = false;

var ratio1609 : boolean = false;

var CamX : GameObject; // drag camera or parent of camera to this slot

// probably I could run this in the start function as long as I set it up before building

function Update () {

// camera X set positions

CamX.transform.position.z = -6.4;

if (ratio0403 == true)
{
CamX.transform.position.z = -6.4;
}

if (ratio0302 == true)
{
CamX.transform.position.z = -5.65;
}

if (ratio1610 == true)
{
CamX.transform.position.z = -5.3;
}

if (ratio1609 == true)
{
CamX.transform.position.z = -4.75;
}

}

If its still any relevance you could just do this at the Start() function of the camera

GetComponent<camera>().aspect = 1.0f;

I set it to 1.0f but it could be anything. You can Read the explanation in the Unity Docs

I created a AssetStore extension that allows for easier aspect switching called AspectSwitcher. It provides a system for allowing you to easily specify different properties for different aspects. There are generally two method that most people use to switch aspects. One is to provide different game objects for each aspect. The other is to create custom code that modifies the properties of a single game object based on the current aspect. That generally requires a lot of custom coding. My extension attempts to alleviate a lot of that pain.

Hi. You could try this asset on the store. You don’t need to stretch anything. Your gameview will neither be distorted nor cut off on the sides. No matter which device with which aspect ratio is using it, your nothing of your game view will get lost. It is available here:

Have fun with it.