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.

Resolved How to keep UI objects inside screen | Screen Space - Overlay

Discussion in 'Immediate Mode GUI (IMGUI)' started by alexbarra, Nov 18, 2022.

?

Was this useful?

  1. Yes

    33.3%
  2. No

    66.7%
  1. alexbarra

    alexbarra

    Joined:
    Feb 2, 2020
    Posts:
    2
    Hello everyone!

    I'm making this post since I've resolved an issue I've been struggling to find a proper solution on the Internet.

    What is this about?
    I had a UI panel that was being positioned in a Screen Space - Overlay canvas, through converting a 3D position to a 2D position (screen/canvas).

    And I had to keep that UI panel inside the screen whether the original position wasn't on screen.

    This worked like a charm for me. This might be done in better way, BUT it works properly.
    For any recommendation/suggestion/comment, don't be afraid to tell me!

    I haven't tried this code in Screen Space - Camera.
    If I've missed a variable or something please also put it. Thanks.

    Solution
    Code (CSharp):
    1.  
    2.  
    3.         [SerializeField] private Vector3 _offSet = Vector3.zero;
    4.         [SerializeField] private Transform _parentTransform;
    5.        
    6.        
    7.         private Camera _mainCamera;
    8.         ///
    9.         private Canvas _canvas;
    10.         ///
    11.         private RectTransform _rectTransform;
    12.         ///
    13.         private Vector3 _worldToScreenPointPosition;
    14.         ///
    15.         private Vector3 _fixedPosition;
    16.         ///
    17.         private float _correctedLeftX;
    18.         private float _correctedRightX;
    19.         ///
    20.         private float _rectLeftX;
    21.         private float _rectRightX;
    22.         ///
    23.         private float _actualRectWidth;
    24.         ///
    25.         private float _worldToScreenPointLeftX;
    26.         private float _worldToScreenPointRightX;
    27.         ///
    28.         private Vector3[] _corners;
    29.  
    30.  
    31.         private void Awake()
    32.         {
    33.             if (_parentTransform == null) Debug.LogError("ParentTransform missing! NULL ERROR");
    34.  
    35.             _mainCamera = Camera.main;
    36.            
    37.             _rectTransform = GetComponent<RectTransform>();
    38.             _canvas = transform.parent.GetComponent<Canvas>();
    39.         }
    40.  
    41.         private void FixedUpdate()
    42.         {
    43.             _worldToScreenPointPosition = _mainCamera.WorldToScreenPoint(_parentTransform.position + _offSet);
    44.            
    45.             //  Update UI panel position to fixed position
    46.             KeepAlwaysOnScreen();
    47.             //-----------------------------------------------
    48.          
    49.             //  Update position
    50.             if (_rectTransform == null) return;
    51.             if (_fixedPosition == Vector3.zero) _fixedPosition = _worldToScreenPointPosition;
    52.  
    53.             _rectTransform.position = _fixedPosition;
    54.             //-----------------
    55.         }
    56.  
    57.         void KeepAlwaysOnScreen()
    58.         {
    59.             //  Get real corners position
    60.             _corners = new Vector3[4];
    61.             _rectTransform.GetWorldCorners(_corners);
    62.  
    63.             _rectLeftX = _corners[0].x;     //  Current value of left X (corners[0] bottom-left corner)
    64.             _rectRightX = _corners[3].x;    //  Current value of right X (corners[0] upper-right corner)
    65.            
    66.             _actualRectWidth = _rectRightX - _rectLeftX;
    67.            
    68.             _worldToScreenPointLeftX = _worldToScreenPointPosition.x - (_actualRectWidth / 2);   //  Original value of left X
    69.             _worldToScreenPointRightX = _worldToScreenPointPosition.x + (_actualRectWidth / 2);  //  Original value of right X
    70.            
    71.            
    72.             _fixedPosition = _worldToScreenPointPosition;
    73.  
    74.            
    75.             //  LEFT SIDE
    76.             if (_worldToScreenPointLeftX < 0)    //  Original value is wrong
    77.             {
    78.                 if (_rectLeftX < 0)  //  Current value is wrong
    79.                 {
    80.                     _correctedLeftX = _worldToScreenPointPosition.x - _rectLeftX + 1;
    81.                     _fixedPosition = new Vector3(_correctedLeftX, _worldToScreenPointPosition.y, _worldToScreenPointPosition.z);
    82.  
    83.                     //Debug.LogWarning("CORRECTING LEFT SIDE");
    84.                 }
    85.                 else if (_correctedLeftX != 0)
    86.                 {
    87.                     _fixedPosition = new Vector3(_correctedLeftX, _worldToScreenPointPosition.y, _worldToScreenPointPosition.z);
    88.                    
    89.                     //Debug.LogWarning("LEFT SIDE CORRECTED");
    90.                 }
    91.             }
    92.             //  RIGHT SIDE
    93.             else if (_worldToScreenPointRightX > _canvas.renderingDisplaySize.x) //  Original value is wrong
    94.             {
    95.                 if (_rectRightX > _canvas.renderingDisplaySize.x)    //  Current value is wrong
    96.                 {
    97.                     _correctedRightX = _worldToScreenPointPosition.x - (_worldToScreenPointRightX - _canvas.renderingDisplaySize.x );
    98.                     _fixedPosition = new Vector3(_correctedRightX, _worldToScreenPointPosition.y, _worldToScreenPointPosition.z);
    99.                    
    100.                     //Debug.LogWarning("CORRECTING RIGHT SIDE");
    101.                 }
    102.                 else if (_correctedRightX != 0)
    103.                 {
    104.                     _fixedPosition = new Vector3(_correctedRightX, _worldToScreenPointPosition.y, _worldToScreenPointPosition.z);
    105.                    
    106.                     //Debug.LogWarning("RIGHT SIDE CORRECTED");
    107.                 }
    108.             }
    109.         }