Advertisement
BlackDragonBE

VisibleOrNot.cs

Jan 21st, 2018
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.64 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using UnityEngine.Events;
  5.  
  6. /// <summary>
  7. /// How to use:
  8. /// Attach to any GameObject and it will report if it's actually visible to a camera or not using a combination of frustrum checking and linecasts.
  9. /// Be sure to hide the Scene view when using this script as the editor camera also triggers OnBecameVisible & OnBecameInvisible (Unity bug)
  10. /// </summary>
  11. public class VisibleOrNot : MonoBehaviour
  12. {
  13.     public delegate void VisibilityHandler(bool isVisible, Vector3 position);
  14.  
  15.     public event VisibilityHandler OnVisibilityChanged;
  16.  
  17.     [Serializable]
  18.     public class VisibilityChangedEvent : UnityEvent<bool, Vector3> { }
  19.  
  20.     public VisibilityChangedEvent OnVisibilityChangedEvent;
  21.  
  22.     [HideInInspector]
  23.     public bool IsVisible;
  24.  
  25.     [Tooltip("WARNING: Will only work once. Be sure to hide the editor view after to avoid editor camera interference.")]
  26.     public bool DrawDebugLines;
  27.  
  28.     [Tooltip("Camera to use for checking visibility. Defaults to main camera if left empty.")]
  29.     public Camera _rayCastCamera;
  30.  
  31.     private bool _potentialToBeVisible = false;
  32.     private Collider _collider;
  33.  
  34.     private void Awake()
  35.     {
  36.         if (!_rayCastCamera)
  37.         {
  38.             _rayCastCamera = Camera.main;
  39.         }
  40.  
  41.         _collider = GetComponent<Collider>();
  42.     }
  43.  
  44.     private void Update()
  45.     {
  46.         if (_potentialToBeVisible)
  47.         {
  48.             if (IsVisible || !IsCameraVisible())
  49.             {
  50.                 // Already triggered visible event or collider blocking view
  51.                 return;
  52.             }
  53.  
  54.             IsVisible = true;
  55.             TriggerVisibilityChangedEvent();
  56.         }
  57.     }
  58.  
  59.     /// <summary>
  60.     /// Check for collisions between this object & the camera from the center + all sides.
  61.     /// Return true if any linecasts can "see" the camera.
  62.     /// </summary>
  63.     /// <returns>Return true if any linecasts can "see" the camera.</returns>
  64.     private bool IsCameraVisible()
  65.     {
  66.         bool camVisible = !Physics.Linecast(transform.position, _rayCastCamera.transform.position) ||
  67.             !Physics.Linecast(transform.position + new Vector3(_collider.bounds.extents.x, 0, 0), _rayCastCamera.transform.position) ||
  68.             !Physics.Linecast(transform.position - new Vector3(_collider.bounds.extents.x, 0, 0), _rayCastCamera.transform.position) ||
  69.             !Physics.Linecast(transform.position + new Vector3(0, _collider.bounds.extents.y, 0), _rayCastCamera.transform.position) ||
  70.             !Physics.Linecast(transform.position - new Vector3(0, _collider.bounds.extents.y, 0), _rayCastCamera.transform.position) ||
  71.             !Physics.Linecast(transform.position + new Vector3(0, 0, _collider.bounds.extents.z), _rayCastCamera.transform.position) ||
  72.             !Physics.Linecast(transform.position - new Vector3(0, 0, _collider.bounds.extents.z), _rayCastCamera.transform.position);
  73.  
  74.         if (DrawDebugLines)
  75.         {
  76.             Debug.DrawLine(transform.position, _rayCastCamera.transform.position, Color.red);
  77.             Debug.DrawLine(transform.position + new Vector3(_collider.bounds.extents.x, 0, 0), _rayCastCamera.transform.position, Color.red);
  78.             Debug.DrawLine(transform.position - new Vector3(_collider.bounds.extents.x, 0, 0), _rayCastCamera.transform.position, Color.red);
  79.             Debug.DrawLine(transform.position + new Vector3(0, _collider.bounds.extents.y, 0), _rayCastCamera.transform.position, Color.red);
  80.             Debug.DrawLine(transform.position - new Vector3(0, _collider.bounds.extents.y, 0), _rayCastCamera.transform.position, Color.red);
  81.             Debug.DrawLine(transform.position + new Vector3(0, 0, _collider.bounds.extents.z), _rayCastCamera.transform.position, Color.red);
  82.             Debug.DrawLine(transform.position - new Vector3(0, 0, _collider.bounds.extents.z), _rayCastCamera.transform.position, Color.red);
  83.         }
  84.  
  85.         return camVisible;
  86.     }
  87.  
  88.     private void OnBecameInvisible()
  89.     {
  90.         _potentialToBeVisible = false;
  91.  
  92.         if (!IsVisible)
  93.         {
  94.             // Don't call event if already invisible (be it out of frustrum or due to a collider blocking the view)
  95.             return;
  96.         }
  97.  
  98.         IsVisible = false;
  99.         TriggerVisibilityChangedEvent();
  100.     }
  101.  
  102.     private void OnBecameVisible()
  103.     {
  104.         _potentialToBeVisible = true;
  105.     }
  106.  
  107.     private void TriggerVisibilityChangedEvent()
  108.     {
  109.         if (OnVisibilityChanged != null)
  110.         {
  111.             OnVisibilityChanged(IsVisible, transform.position);
  112.             OnVisibilityChangedEvent.Invoke(IsVisible, transform.position);
  113.         }
  114.     }
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement