RectTransformExtension.cs 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public static class RectTransformExtension
  5. {/// <summary>
  6. /// Counts the bounding box corners of the given RectTransform that are visible in screen space.
  7. /// </summary>
  8. /// <returns>The amount of bounding box corners that are visible.</returns>
  9. /// <param name="rectTransform">Rect transform.</param>
  10. /// <param name="camera">Camera. Leave it null for Overlay Canvasses.</param>
  11. private static int CountCornersVisibleFrom(this RectTransform rectTransform, Camera camera = null)
  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);
  16. int visibleCorners = 0;
  17. Vector3 tempScreenSpaceCorner; // Cached
  18. for (var i = 0; i < objectCorners.Length; i++) // For each corner in rectTransform
  19. {
  20. if (camera != null)
  21. tempScreenSpaceCorner = camera.WorldToScreenPoint(objectCorners[i]); // Transform world space position of corner to screen space
  22. else
  23. {
  24. Debug.Log(rectTransform.gameObject.name + " :: " + objectCorners[i].ToString("F2"));
  25. tempScreenSpaceCorner = objectCorners[i]; // If no camera is provided we assume the canvas is Overlay and world space == screen space
  26. }
  27. if (screenBounds.Contains(tempScreenSpaceCorner)) // If the corner is inside the screen
  28. {
  29. visibleCorners++;
  30. }
  31. }
  32. return visibleCorners;
  33. }
  34. /// <summary>
  35. /// Determines if this RectTransform is fully visible.
  36. /// Works by checking if each bounding box corner of this RectTransform is inside the screen space view frustrum.
  37. /// </summary>
  38. /// <returns><c>true</c> if is fully visible; otherwise, <c>false</c>.</returns>
  39. /// <param name="rectTransform">Rect transform.</param>
  40. /// <param name="camera">Camera. Leave it null for Overlay Canvasses.</param>
  41. public static bool IsFullyVisibleFrom(this RectTransform rectTransform, Camera camera = null)
  42. {
  43. if (!rectTransform.gameObject.activeInHierarchy)
  44. return false;
  45. return CountCornersVisibleFrom(rectTransform, camera) == 4; // True if all 4 corners are visible
  46. }
  47. /// <summary>
  48. /// Determines if this RectTransform is at least partially visible.
  49. /// Works by checking if any bounding box corner of this RectTransform is inside the screen space view frustrum.
  50. /// </summary>
  51. /// <returns><c>true</c> if is at least partially visible; otherwise, <c>false</c>.</returns>
  52. /// <param name="rectTransform">Rect transform.</param>
  53. /// <param name="camera">Camera. Leave it null for Overlay Canvasses.</param>
  54. public static bool IsVisibleFrom(this RectTransform rectTransform, Camera camera = null)
  55. {
  56. /*
  57. if(camera == null)
  58. {
  59. return false;
  60. }
  61. if (!rectTransform.gameObject.activeInHierarchy)
  62. return false;
  63. */
  64. //modified
  65. Rect screenBounds = new Rect(0f, 0f, Screen.width, Screen.height); // Screen space bounds (assumes camera renders across the entire screen)
  66. Vector3[] objectCorners = new Vector3[4];
  67. rectTransform.GetWorldCorners(objectCorners);
  68. int visibleCorners = 0;
  69. Vector3 tempScreenSpaceCorner; // Cached
  70. for (var i = 0; i < objectCorners.Length; i++) // For each corner in rectTransform
  71. {
  72. tempScreenSpaceCorner = camera.WorldToScreenPoint(objectCorners[i]); // Transform world space position of corner to screen space
  73. if (screenBounds.Contains(tempScreenSpaceCorner)) // If the corner is inside the screen
  74. {
  75. visibleCorners++;
  76. }
  77. }
  78. //modified
  79. return CountCornersVisibleFrom(rectTransform, camera) > 0; // True if any corners are visible
  80. }
  81. }