Search Unity

  1. We want you to join us at GDC this year! We've added new sessions to Unity Central, space is limited so sign up now!
    Dismiss Notice
  2. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  3. Unity 2017.3 has arrived! Read about it here.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Tell us about your experience here and you’ll get early access to the 2018 Game Studios report + more goodies.
    Dismiss Notice
  6. Be the first to take a peek at upcoming 2D Animation Preview. Drop into the forum and check it out!
    Dismiss Notice
  7. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Test if UI element is visible on screen

Discussion in 'Unity UI & TextMesh Pro' started by mimminito, Oct 28, 2014.

  1. mimminito


    Feb 10, 2010

    I am trying to test if a UI element is visible on the screen. Im currently using a Image control, and would like to know if its visible by the camera, or if its outside of its bounds. I cannot seem to find a way to determine this, and as we do not have a renderer component I cannot do a GeometryUtility.TestPlanesAABB test.
    Any help would be appreciated.

  2. KGC


    Oct 2, 2014
    Sorry for necroing an old post, but I had a similar issue today, and could not find a complete solution via Goggle, so I wrote my own based on the fragmented solutions I could find on Unity Answers. Tested on a Canvas set to Screen Space Camera mode.

    Code (CSharp):
    1. bool isFullyVisible = myRectTransform.IsFullyVisibleFrom(myCamera);

    Code (CSharp):
    1. using UnityEngine;
    3. public static class RendererExtensions
    4. {
    5.     /// <summary>
    6.     /// Counts the bounding box corners of the given RectTransform that are visible from the given Camera in screen space.
    7.     /// </summary>
    8.     /// <returns>The amount of bounding box corners that are visible from the Camera.</returns>
    9.     /// <param name="rectTransform">Rect transform.</param>
    10.     /// <param name="camera">Camera.</param>
    11.     private static int CountCornersVisibleFrom(this RectTransform rectTransform, Camera camera)
    12.     {
    13.         Rect screenBounds = new Rect(0f, 0f, Screen.width, Screen.height); // Screen space bounds (assumes camera renders across the entire screen)
    14.         Vector3[] objectCorners = new Vector3[4];
    15.         rectTransform.GetWorldCorners(objectCorners);
    17.         int visibleCorners = 0;
    18.         Vector3 tempScreenSpaceCorner; // Cached
    19.         for (var i = 0; i < objectCorners.Length; i++) // For each corner in rectTransform
    20.         {
    21.             tempScreenSpaceCorner = camera.WorldToScreenPoint(objectCorners[i]); // Transform world space position of corner to screen space
    22.             if (screenBounds.Contains(tempScreenSpaceCorner)) // If the corner is inside the screen
    23.             {
    24.                 visibleCorners++;
    25.             }
    26.         }
    27.         return visibleCorners;
    28.     }
    30.     /// <summary>
    31.     /// Determines if this RectTransform is fully visible from the specified camera.
    32.     /// Works by checking if each bounding box corner of this RectTransform is inside the cameras screen space view frustrum.
    33.     /// </summary>
    34.     /// <returns><c>true</c> if is fully visible from the specified camera; otherwise, <c>false</c>.</returns>
    35.     /// <param name="rectTransform">Rect transform.</param>
    36.     /// <param name="camera">Camera.</param>
    37.     public static bool IsFullyVisibleFrom(this RectTransform rectTransform, Camera camera)
    38.     {
    39.         return CountCornersVisibleFrom(rectTransform, camera) == 4; // True if all 4 corners are visible
    40.     }
    42.     /// <summary>
    43.     /// Determines if this RectTransform is at least partially visible from the specified camera.
    44.     /// Works by checking if any bounding box corner of this RectTransform is inside the cameras screen space view frustrum.
    45.     /// </summary>
    46.     /// <returns><c>true</c> if is at least partially visible from the specified camera; otherwise, <c>false</c>.</returns>
    47.     /// <param name="rectTransform">Rect transform.</param>
    48.     /// <param name="camera">Camera.</param>
    49.     public static bool IsVisibleFrom(this RectTransform rectTransform, Camera camera)
    50.     {
    51.         return CountCornersVisibleFrom(rectTransform, camera) > 0; // True if any corners are visible
    52.     }
    53. }
    Last edited: Mar 2, 2017
  3. Anisoropos


    Jul 30, 2012
    Thanks @KGC , your code works like a charm, is well documented and abides to best practices (static helper functions with private functionality and public accessors). :)
  4. nngafook


    Sep 7, 2013
    @KGC, you're a god!
    Thanks! <3
  5. Sir-Gatlin


    Jan 18, 2013
    Thank you! this is awesome. Noob question, where would be the best place to implement this? does it have to go into the update method? or is there a better way to listen for it to change?
  6. diegoadrada


    Nov 27, 2014
    I have the same doubt, because call this from update method doesn't looks like an optimal way.
    Sir-Gatlin likes this.
  7. KGC


    Oct 2, 2014
    So in our project we use it to check if a UI animation should play. In that case we use a coroutine that checks either every frame or with some time delay (i think its the latter). It really depends. If you need to know with highest precision, then yes, put it in an update function. But you could probably get away with calling it only every 5th frame or so - in that that just use a coroutine :)
    Sir-Gatlin likes this.
  8. CalebBarton


    Jun 24, 2017
    Thanks for the post KGC. I was just about to develop something similar, but you've taken the hard work out for me.
  9. YoungDeveloper


    Jun 28, 2013
    If you are caching Vector3 tempScreenSpaceCorner then you might especially do it with .Length