Search Unity

Supporting Widescreen on a camera clamping script?

Discussion in 'Scripting' started by DevMerlin, May 23, 2020.

  1. DevMerlin

    DevMerlin

    Joined:
    Dec 21, 2011
    Posts:
    96
    I have a script that controls what the bounds of an Orthographic camera are, somewhat loosely based on shieldgenerator7's answer here, from this thread: https://answers.unity.com/questions/433665/need-help-with-2d-orthographic-camera-zooming.htm

    It works ALMOST perfectly. However... when it hits widescreen layouts, it's got severe jitter issues. It has a tendency to flip back and forth, and never stay in one place after screen sizes past 16:x are tried. The camera itself is rotated slightly by 10 on x, however this otherwise works perfectly for 3:2, 4:3, and 5:4.

    Is there any good way to handle widescreen sizes with camera bounding boxes? The script I have so far is below:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraController : MonoBehaviour
    6. {
    7.     public Camera screenCamera;
    8.     public GameObject boundsMarker;
    9.     public Bounds visibleBounds;
    10.     public Transform playerTarget;
    11.    
    12.     [SerializeField]
    13.     float boundingBoxPadding = 2f;
    14.  
    15.     [SerializeField]
    16.     float minimumOrthographicSize = 5f;
    17.     [SerializeField]
    18.     float zoomSpeed = 20f;
    19.  
    20.     Vector2 cameraSizeWorld;
    21.     Vector2 halfSize;
    22.  
    23.     private void Awake()
    24.     {
    25.         screenCamera = GetComponent<Camera>();
    26.     }
    27.  
    28.     // Start is called before the first frame update
    29.     void Start()
    30.     {
    31.         playerTarget = WorldController.Instance.cameraTarget;
    32.         Vector3 tPos = playerTarget.position;
    33.         tPos.z = -20;
    34.         transform.position = tPos;
    35.     }
    36.  
    37.     private void FixedUpdate()
    38.     {
    39.         // In case the box gets updated during play //
    40.         visibleBounds = boundsMarker.GetComponent<BoxCollider>().bounds;
    41.  
    42.         if (playerTarget != null)
    43.         {
    44.             Vector3 tPos = playerTarget.position;
    45.             tPos.z = -20;
    46.             transform.position = tPos;
    47.             updateExtents();
    48.         }
    49.     }
    50.  
    51.     private void updateExtents()
    52.     {
    53.         cameraSizeWorld = Camera.main.ViewportToWorldPoint(Vector2.one) - Camera.main.ViewportToWorldPoint(Vector2.zero);
    54.         halfSize = cameraSizeWorld / 2;
    55.     }
    56.  
    57.     private void LateUpdate()
    58.     {
    59.         Vector3 v3 = transform.position;
    60.         v3.x = Mathf.Clamp(v3.x, visibleBounds.min.x + halfSize.x, visibleBounds.max.x - halfSize.x);
    61.         v3.y = Mathf.Clamp(v3.y, visibleBounds.min.y + halfSize.y, visibleBounds.max.y - halfSize.y);
    62.         transform.position = v3;
    63.     }
    64. }
    65.  
     
    shieldgenerator7 likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    I think it might be a timing problem because FixedUpdate and LateUpdate are on separate loops, as this diagram shows:

    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Try this: instead of using LateUpdate(), make your own "MyLateUpdate()" and make it public, then call it directly at the end of your player's FixedUpdate(), obviously giving the player a reference to this script in one of the usual Unity ways.

    Actually, come to think of it, do that but ALSO combine the code presently in the FixedUpdate() into this new MyLateUpdate(), obviously doing the updateExtents first, then the clamps.
     
  3. DevMerlin

    DevMerlin

    Joined:
    Dec 21, 2011
    Posts:
    96
    That seems possibly logical... however, it -only- starts happening when the viewing angle goes into Widescreen: Specifically, 16:10 and 16:9 on the Editor. Everything else is just fine. I don't think that's an update order issue exactly, but I will test it.
     
  4. DevMerlin

    DevMerlin

    Joined:
    Dec 21, 2011
    Posts:
    96
    It both did and didn't work. It now encompasses the entire stage, which it should do... but it also breaks following the target, and doesn't resize at all with everything outside LateUpdate. I think LateUpdate is essential for this to fully work.
     
    Last edited: May 24, 2020
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Your updateExtents certainly seems extremely straightforward, as does the clamping.

    Why don't you start putting some of those various values in a debug UI.Text object onscreen and see why comparisons are doing what they're doing?

    Since it is an ortho camera it should not care how wide it is. With a perspective camera I suppose there might be weirdness in the bounds once the lateral FOV width reaches 180 degrees...
     
  6. shieldgenerator7

    shieldgenerator7

    Joined:
    Dec 20, 2015
    Posts:
    39
    The link's broken now.

    But I imagine it might have something to do with the camera view being larger than the bounding box. I never tested such a case. Did you happen to solve this issue already?