Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Letterboxing with a background instead of black bars.

Discussion in 'Scripting' started by flytraparts, Aug 9, 2023.

  1. flytraparts

    flytraparts

    Joined:
    Dec 2, 2019
    Posts:
    11
    Hi there.

    I have this mobile game I'm making for a client where the game is made for an 18:9 aspect ratio.
    I wanted to make an adaptive UI, but he insisted on a fixed aspect ratio.

    Several months later, he wants the blacks bars to be removed, but without changing the aspect ratio of the game and instead extend the background images for each ui element.

    here is the code for the letterboxing.

    Code (CSharp):
    1.   private void HandleBestFit()
    2.         {
    3.             int nearestWidth = currentScreenWidth / targetWidth * targetWidth;
    4.             int nearestHeight = currentScreenHeight / targetHeight * targetHeight;
    5.  
    6.             int scaleFactor = GetScaleFactor(nearestWidth, nearestHeight);
    7.             float xWidthFactor = targetWidth * scaleFactor / (float)currentScreenWidth;
    8.             float yHeightFactor = targetHeight * scaleFactor / (float)currentScreenHeight;
    9.  
    10.             Camera.rect = new Rect(GetRectPosition(xWidthFactor, currentScreenWidth), GetRectPosition(yHeightFactor, currentScreenHeight), xWidthFactor, yHeightFactor);
    11.         }
    12.         private Rect GetLetterboxRect(float scaleHeight)
    13.         {
    14.             return new Rect(0, (1f - scaleHeight) / 2f, 1f, scaleHeight);
    15.         }
    the game has different panels, each one has a different background, and the panels canvas has a screenspace render mode where the letterboxed camera being referenced

    my question is how would I have the black bars be hidden by the extended backgrounds that should adapt to every aspect ratio without changing the rest of the game.

    Thank you and sorry for the long post.
     
    Last edited: Aug 9, 2023
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    Just make your background and put it on a separate Canvas layered behind everything.

    Put an AspectRatioFitter on it and set it to engulf the entire screen and stretch to it, and key in the aspect ratio of the source image to make it not distort.

    Done.
     
    flytraparts and Bunny83 like this.
  3. flytraparts

    flytraparts

    Joined:
    Dec 2, 2019
    Posts:
    11
    Thank you, I thought about that, but unfortunately I have a lot of UI elements with each one having a separate background.
    This is a pretty UI heavy game, so in this case this wouldn't work.

    I thought about having a separate camera that only shows the background layer and use a Render texture to display it.
    But it didn't work because it won't show up since the canvas is referencing the main camera.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    Then just put two chunks of BG in and bring the edges of them in (with your own code) to avoid overdraw.
     
    flytraparts likes this.
  5. flytraparts

    flytraparts

    Joined:
    Dec 2, 2019
    Posts:
    11
    That also wouldn't work, because the black bars are just the camera not rendering anything.
    So even if I stretch them out, they won't show up, that why I wanted to add another camera that only shows the background and show it in another canvas.

    If I knew how to keep the game in a certain aspect ratio without touching the viewport rect and fill up the rest with the background, it would make things easier.

    I'll try to find a solution for that.
    Thanks for trying.
     
  6. flytraparts

    flytraparts

    Joined:
    Dec 2, 2019
    Posts:
    11
    Update, I managed to fix it a few days ago and might as well post it in case someone ever encounters this problem.

    I changed all canvas screen match modes to Expand while you set the correct reference resolution.
    I added an aspect ratio fitter to all backgrounds, set the aspect mode to envelope parent.

    and lastly the camera orthographic size, here is the code


    Code (CSharp):
    1. public class AdjustOrthographicSize : MonoBehaviour
    2. {
    3.     [SerializeField] private float _targetAspectRatio = .5f;
    4.     private float _originalOrthographicSize;
    5.     private float _originalWidthInWorldUnits;
    6.     private Camera _camera;
    7.  
    8.     private Camera Camera
    9.     {
    10.         get
    11.         {
    12.             if (!_camera)
    13.             {
    14.                 _camera = GetComponent<Camera>();
    15.  
    16.                 _originalOrthographicSize = _camera.orthographicSize;
    17.  
    18.                 _originalWidthInWorldUnits = 2f * _originalOrthographicSize * _targetAspectRatio;
    19.             }
    20.             return _camera;
    21.         }
    22.     }
    23.  
    24.     private void Awake()
    25.     {
    26.         UpdateRatio();
    27.     }
    28.  
    29.     private void UpdateRatio()
    30.     {
    31.         float orthographicSize = Camera.orthographicSize;
    32.         float targetOrthographicSize;
    33.  
    34.         float deviceWidth = Screen.width;
    35.         float deviceHeight = Screen.height;
    36.  
    37.         float aspectRatio = deviceWidth / deviceHeight;
    38.  
    39.         float widthInWorldUnits = 2f * orthographicSize * aspectRatio;
    40.  
    41.         targetOrthographicSize = _originalOrthographicSize + ((_originalWidthInWorldUnits - widthInWorldUnits) / 2f)/  aspectRatio;
    42.  
    43.         Camera.orthographicSize = Mathf.Max(targetOrthographicSize, _originalOrthographicSize);
    44.     }
    45. }
     
    Last edited: Aug 14, 2023