Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Showcase Showing 3D stuff inside responsive UI

Discussion in 'UGUI & TextMesh Pro' started by gilzoide, Nov 21, 2022.

  1. gilzoide

    gilzoide

    Joined:
    Oct 7, 2015
    Posts:
    27
    Hi folks! Today I'd like to show you a simple script I made for dynamically fitting the contents of a Camera directly into UI rectangles (RectTransform inside Canvases): CameraViewportRect
    It supports both Screen Space - Camera and Screen Space - Overlay modes and disabling the Camera whenever the script itself gets disabled, so the Camera can stop rendering when the UI object gets destroyed/deactivated.

    (I tried adding a GIF here showing it in action, but the forum won't let me, here's a link if anyone is interested)

    The code is open source at https://github.com/gilzoide/unity-camera-viewport-rect and is installable via Open UPM, directly via UPM with the Git URL or you can just copy the code for the single script file to your projects.

    Any feedback is appreciated ^^

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace Gilzoide.CameraViewportRect
    4. {
    5.     [RequireComponent(typeof(RectTransform)), ExecuteAlways]
    6.     public class CameraViewportRect : MonoBehaviour
    7.     {
    8.         [Tooltip("Target Camera")]
    9.         [SerializeField] protected Camera _camera;
    10.  
    11.         [Tooltip("Toggle Camera.enabled when this script gets enabled/disabled")]
    12.         public bool ToggleCameraEnabled = true;
    13.  
    14.         public Camera Camera
    15.         {
    16.             get => _camera;
    17.             set
    18.             {
    19.                 _camera = value;
    20.                 if (isActiveAndEnabled)
    21.                 {
    22.                     RefreshCameraRect();
    23.                 }
    24.             }
    25.         }
    26.  
    27.         protected Canvas _canvas;
    28.         protected readonly Vector3[] _worldCorners = new Vector3[4];
    29.  
    30.         public void RefreshCameraRect()
    31.         {
    32.             if (Camera && _canvas)
    33.             {
    34.                 Camera.pixelRect = GetScreenRect();
    35.             }
    36.         }
    37.  
    38.         protected virtual void Update()
    39.         {
    40.             if (transform.hasChanged)
    41.             {
    42.                 RefreshCameraRect();
    43.             }
    44.         }
    45.  
    46.         protected virtual void OnEnable()
    47.         {
    48.             _canvas = FindRootCanvas();
    49.             if (ToggleCameraEnabled && Camera)
    50.             {
    51.                 Camera.enabled = true;
    52.             }
    53.         }
    54.  
    55.         protected virtual void OnDisable()
    56.         {
    57.             if (ToggleCameraEnabled && Camera)
    58.             {
    59.                 Camera.enabled = false;
    60.             }
    61.         }
    62.  
    63.         protected virtual void OnTransformParentChanged()
    64.         {
    65.             if (isActiveAndEnabled)
    66.             {
    67.                 _canvas = FindRootCanvas();
    68.                 RefreshCameraRect();
    69.             }
    70.         }
    71.  
    72. #if UNITY_EDITOR
    73.         protected virtual void OnValidate()
    74.         {
    75.             if (isActiveAndEnabled)
    76.             {
    77.                 RefreshCameraRect();
    78.             }
    79.         }
    80. #endif
    81.  
    82.         protected Rect GetScreenRect()
    83.         {
    84.             ((RectTransform) transform).GetWorldCorners(_worldCorners);
    85.             Vector3 bottomLeft = _worldCorners[0];
    86.             Vector3 topRight = _worldCorners[2];
    87.             if (_canvas.renderMode == RenderMode.ScreenSpaceCamera && _canvas.worldCamera != null)
    88.             {
    89.                 Camera camera = _canvas.worldCamera;
    90.                 bottomLeft = camera.WorldToScreenPoint(bottomLeft);
    91.                 topRight = camera.WorldToScreenPoint(topRight);
    92.             }
    93.             return Rect.MinMaxRect(bottomLeft.x, bottomLeft.y, topRight.x, topRight.y);
    94.         }
    95.  
    96.         protected Canvas FindRootCanvas()
    97.         {
    98.             Canvas canvas = GetComponentInParent<Canvas>();
    99.             return canvas != null ? canvas.rootCanvas : null;
    100.         }
    101.     }
    102. }
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
  3. gilzoide

    gilzoide

    Joined:
    Oct 7, 2015
    Posts:
    27
    Thanks @SimonDarksideJ!

    Well, sure! More availability, more people with one more handy script to ease their development ^^