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. Dismiss Notice

[SOLVED] How to check is a button is outside the camera view?

Discussion in 'Scripting' started by Deleted User, Feb 11, 2015.

  1. Deleted User

    Deleted User

    Guest

    I want to check if a button is outside a camera view.
     
  2. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
  3. Deleted User

    Deleted User

    Guest

  4. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    I haven't used the new UI classes yet, so bear with me because I don't really know what I am talking about :)

    I assume that the button script you have assigned is on a game object that does not directly have a renderer component attached, but there is probably a renderer component somewhere in your button hierarchy (maybe a child game object) that you can check (like a sprite renderer that you "see" the button with?) When you click on the button's image, you should see the renderer in the inspector.

    Again though, I haven't used the new UI at all yet, so I hope I'm not leading you on a goose chase.
     
  5. Deleted User

    Deleted User

    Guest

    Np thanks for trying to help. :)

    The button only has a transform, an image, a button component and a child Text object.
     
  6. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Assuming it's a world space button - convert world space to screen space and check if the result is less than 0 or greater than the height/width of the screen.
     
  7. Deleted User

    Deleted User

    Guest

    The canvas is set to Screen Space - Camera.
     
  8. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Then shouldn't the button already be in screen space?
     
  9. Deleted User

    Deleted User

    Guest

    I don't think so. I think I tried it already. I'll post the results once I get home.
    The thing about the camera is that the Viewport width is about 60% and the height is about 25% and is not centered.
     
  10. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Ok - either way. If the coordinates of the RectTransform fall outside of the viewport for the camera then it's not "in" the camera. If you're checking the entirety of the UI element then you'll have to compensate for half the height and width but that should be trivial.
     
  11. Deleted User

    Deleted User

    Guest

    I checked the position of the object by calling "gameObject.GetComponent<RectTransform>().position" and it usually returns a value between -10 (off screen to the left) and 5 (off screen to the right)
    Screen.width returns the size of the screen in pixel.
    Calling camera.rect gives me (x:0.19, y:0.10, width:0.62, height:0.80)
     
  12. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    Here ya go. I downloaded the latest Unity just so I could get the UI tools and try to solve this :)

    Code (CSharp):
    1. public class NewBehaviourScript : MonoBehaviour {
    2.     public RectTransform canvasRect;
    3.     public RectTransform buttonRect;
    4.  
    5.     // Use this for initialization
    6.     void Start () {
    7.  
    8.     }
    9.  
    10.     // Update is called once per frame
    11.     void Update () {
    12.         Bounds canvasBounds = new Bounds(new Vector3(canvasRect.position.x, canvasRect.position.y, 0), new Vector3(canvasRect.sizeDelta.x, canvasRect.sizeDelta.y, 1));
    13.         Bounds buttonBounds = new Bounds(new Vector3(buttonRect.position.x, buttonRect.position.y, 0), new Vector3(buttonRect.sizeDelta.x, buttonRect.sizeDelta.y, 1));
    14.  
    15.         if(buttonBounds.Intersects (canvasBounds))
    16.             Debug.Log ("Visible");
    17.         else
    18.             Debug.Log ("Not visible");
    19.     }
    20. }
    21.  
     
  13. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    I guess that assumes that the canvas is filling the screen. If not, hopefully this will be enough to get you rolling. if you need more help, just let me know.
     
  14. Deleted User

    Deleted User

    Guest

    @gtzpower unfortunately it's not working for me. :( It always displays Visible even when the button is not visible on the camera. I think it's because it probably works through the canvas but not the camera and the camera I'm using only renders about 1/4 of the screen (1/2 width, 1/2 height).
     
  15. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    I Modified it to work with a camera. Give this a shot:
    Code (CSharp):
    1. public class NewBehaviourScript : MonoBehaviour {
    2.  
    3.     public Camera cameraToTest;
    4.     public RectTransform buttonRect;
    5.  
    6.     // Use this for initialization
    7.     void Start () {
    8.  
    9.     }
    10.  
    11.     // Update is called once per frame
    12.     void Update () {
    13.         Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cameraToTest);
    14.         Bounds buttonBounds = new Bounds(new Vector3(buttonRect.position.x, buttonRect.position.y, buttonRect.position.z), new Vector3(buttonRect.sizeDelta.x, buttonRect.sizeDelta.y, 1));
    15.  
    16.         if(GeometryUtility.TestPlanesAABB(planes,buttonBounds))
    17.             Debug.Log ("Visible");
    18.         else
    19.             Debug.Log ("Not visible");
    20.     }
    21. }
     
    Deleted User likes this.
  16. Deleted User

    Deleted User

    Guest

    Unfortunately, it doesn't work. No matter where I move the button to, it always prints "Visible". Even if I deactivate the button.
     
  17. Deleted User

    Deleted User

    Guest

    I think you're on to something with the bounds but I'm not sure if "buttonRect.position" is accurate for the camera. You know what I mean? I think it might need to be converted.

    I've tried so many things. GRRRRR.

    Edit: This can get the camera bounds since my cam is Orthographic.


    Code (CSharp):
    1.         public static Bounds OrthographicBounds (this Camera camera)
    2.         {
    3.                 float screenAspect = (float)Screen.width / (float)Screen.height;
    4.                 float cameraHeight = camera.orthographicSize * 2.0f;
    5.                 return new Bounds (camera.transform.position, new Vector3 (cameraHeight * screenAspect, cameraHeight, 0));
    6.         }
    7.  
     
  18. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    Can you try out the attached project? It works for me. Just load it up, hit play, and move the button around in the editor. Maybe you can spot a difference in how mine is setup versus yours?
     

    Attached Files:

    • GUI.zip
      File size:
      146.8 KB
      Views:
      461
    Deleted User likes this.
  19. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    I just tried switching my camera to orthographic per your edit, and my script still worked for me. :/
     
  20. Deleted User

    Deleted User

    Guest

    Try this:
    Change the Canvas to Screen Camera and underneath it, set "Render Camera" to your camera and then it won't work. :(
    But for my project, render camera needs to be set. I could create a third camera maybe...
     
  21. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    Tried setting "Screen Space - Camera" if thats what you mean, then assigned my camera to the Render Camera, and it still worked. I didn't see a "Screen Camera" option.

    I gotta go for the evening, will check in in the morn.
     
  22. Deleted User

    Deleted User

    Guest

    Did you also set the cam to orthographic? If you don't set it, it doesn't work well though because you have to drag the button pretty far out of the field of view for it to become not visible.
     
  23. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    Ok, sorry, I did not have both orthographic and Screen Space - Camera set. I see the issues you see now, and I revamped the script. This new GUI stuff is a different animal, but I think I have the solution:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class NewBehaviourScript : MonoBehaviour {
    5.  
    6.     public Camera cameraToTest;
    7.     public RectTransform buttonRect;
    8.  
    9.     // Use this for initialization
    10.     void Start () {
    11.    
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update () {
    16.         Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cameraToTest);
    17.  
    18.         float fUiUnitToWorldUnit = Screen.height / (cameraToTest.orthographicSize * 2);
    19.  
    20.         Bounds buttonBounds = new Bounds(new Vector3(buttonRect.position.x, buttonRect.position.y, buttonRect.position.z),
    21.                                          new Vector3(buttonRect.sizeDelta.x/fUiUnitToWorldUnit, buttonRect.sizeDelta.y/fUiUnitToWorldUnit, 1));
    22.  
    23.         if(GeometryUtility.TestPlanesAABB(planes,buttonBounds))
    24.             Debug.Log ("Visible");
    25.         else
    26.             Debug.Log ("Not visible");
    27.     }
    28. }
    29.  
    Here is my entire project if that helps.
     

    Attached Files:

    • GUI.zip
      File size:
      149.1 KB
      Views:
      473
    Deleted User likes this.
  24. Deleted User

    Deleted User

    Guest

    Thanks a lot for your help. :)
    I'll try it out once I get home and let you know.
     
  25. Deleted User

    Deleted User

    Guest

    @gtzpower wow this is just baffling. Your script works perfectly but here's the thing: when I import it in my game, it doesn't work 100% for my existing buttons: when my buttons are halfway showing to the right or to the bottom, it will show as "not visible"; they need to be more than 50% hidden for it to show "visible" BUT when my buttons are on the left or top of the camera, they need to be a bit more than 100% hidden for it to show "not visible".

    Here's the crazy thing though: when I create a new button, it works perfectly! I don't understand why because my existing buttons and the new ones all have their anchors set to "Center".

    EDIT: Figured it out. Has to do with the pivot: if the size is not set to .5, then the script won't work well. Also I noticed it's possible for a button to be *slightly visible* but still show as not visible.
     
    Last edited by a moderator: Feb 13, 2015
  26. gtzpower

    gtzpower

    Joined:
    Jan 23, 2011
    Posts:
    318
    I wonder if the last part is scaling related. I can imagine problems if the scale is not 1, in which case you would probably want to multiply the deltaSize by the scale.

    Hopefully this is enough to get you going though :)
     
    Deleted User likes this.
  27. Deleted User

    Deleted User

    Guest

    The scale is set to 1.00. I added + .8 to the bounds and that seems to be OK for now for my needs. Thanks a lot. Although if someone can shed light on this, that'd be great. :p