Advertisement
Guest User

CullingManager.cs

a guest
Dec 23rd, 2021
915
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.99 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class CullingManager : MonoBehaviour
  6. {
  7.  
  8.     public float m_occlusionCapsuleHeight = 0f;
  9.  
  10.     public float m_occlusionCapsuleRadius = 1f;
  11.  
  12.     // list of objects that will trigger the culling effect
  13.     public List<GameObject> m_importantObjects = new List<GameObject>();
  14.  
  15.     // include the mouse in the important objects
  16.     public bool m_includeMouse;
  17.  
  18.     public LayerMask m_layerMask;
  19.  
  20.  
  21.     // List of all the objects that we've set to occluding state
  22.     private List<Cullable> m_occludingObjects = new List<Cullable>();
  23.  
  24.    
  25.     List<Cullable> cullableList = new List<Cullable>();
  26.  
  27.  
  28.    
  29.  
  30.     // Update is called once per frame // Handle per frame logic
  31.     public void Update()
  32.     {
  33.         // Can only do occlusion checks if we have a camera
  34.         if (Camera.main != null)
  35.         {
  36.             // This is the list of positions we're trying not to occlude
  37.             List<Vector3> importantPositions = FindImportantPositions();
  38.  
  39.             // This is the list of objects whihc are in the way
  40.             List<Cullable> newOccludingObjects = FindOccludingObjects(importantPositions);
  41.  
  42.             SetOccludingObjects(newOccludingObjects);
  43.         }
  44.     }
  45.  
  46.     private List<Vector3> FindImportantPositions()
  47.     {
  48.         List<Vector3> positions = new List<Vector3>();
  49.  
  50.  
  51.         // All units are important
  52.         foreach (GameObject unit in m_importantObjects)
  53.         {
  54.             positions.Add(unit.transform.position);
  55.         }
  56.  
  57.  
  58.         if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, 100, m_layerMask) && m_includeMouse)
  59.         {
  60.             Vector3 mousePos = hit.point;
  61.             if (!positions.Contains(mousePos))
  62.             {
  63.                 positions.Add(mousePos);
  64.             }
  65.         }
  66.  
  67.         return positions;
  68.     }
  69.  
  70.     // Update the stored list of occluding objects
  71.     private void SetOccludingObjects(List<Cullable> newList)
  72.     {
  73.         foreach (Cullable cullable in newList)
  74.         {
  75.             int foundIndex = m_occludingObjects.IndexOf(cullable);
  76.  
  77.             if (foundIndex < 0)
  78.             {
  79.                 // This object isnt in the old list, so we need to mark it as occluding
  80.                 cullable.Occluding = true;
  81.             }
  82.             else
  83.             {
  84.                 // This object was already in the list, so remove it from the old list
  85.                 m_occludingObjects.RemoveAt(foundIndex);
  86.             }
  87.         }
  88.  
  89.         // Any object left in the old list, was not in the new list, so it's no longer occludding
  90.         foreach (Cullable cullable in m_occludingObjects)
  91.         {
  92.             cullable.Occluding = false;
  93.         }
  94.  
  95.         m_occludingObjects = newList;
  96.     }
  97.  
  98.     private List<Cullable> FindOccludingObjects(List<Vector3> importantPositions)
  99.     {
  100.         List<Cullable> occludingObjects = new List<Cullable>();
  101.  
  102.  
  103.         Camera camera = Camera.main;
  104.  
  105.         // We want to do a capsule check from each position to the camera, any cullable object we hit should be culled
  106.         foreach (Vector3 pos in importantPositions)
  107.         {
  108.             Vector3 capsuleStart = (pos);
  109.             capsuleStart.y += m_occlusionCapsuleHeight;
  110.  
  111.             Collider[] colliders = Physics.OverlapCapsule(capsuleStart, camera.transform.position, m_occlusionCapsuleRadius, m_layerMask, QueryTriggerInteraction.Ignore);
  112.  
  113.             // Add cullable objects we found to the list
  114.             foreach (Collider collider in colliders)
  115.             {
  116.                 Cullable cullable = collider.GetComponent<Cullable>();
  117.                 Debug.Assert(cullable != null, "Found an object on the occlusion layer without the occlusion component!");
  118.  
  119.                 if (!occludingObjects.Contains(cullable))
  120.                 {
  121.                     occludingObjects.Add(cullable);
  122.                 }
  123.             }
  124.         }
  125.  
  126.         return occludingObjects;
  127.     }
  128. }
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement