unity3d
CullingGroup API
Zoeken…
Opmerkingen
Omdat het gebruik van CullingGroups niet altijd even eenvoudig is, kan het nuttig zijn om het grootste deel van de logica achter een managerklasse in te kapselen.
Hieronder is een blauwdruk hoe een dergelijke manager zou kunnen werken.
using UnityEngine;
using System;
public interface ICullingGroupManager
{
int ReserveSphere();
void ReleaseSphere(int sphereIndex);
void SetPosition(int sphereIndex, Vector3 position);
void SetRadius(int sphereIndex, float radius);
void SetCullingEvent(int sphereIndex, Action<CullingGroupEvent> sphere);
}
De kern ervan is dat u een ruimende bol van de manager reserveert die de index van de gereserveerde bol teruggeeft. U gebruikt vervolgens de gegeven index om uw gereserveerde bol te manipuleren.
Afstanden tot objecten
Het volgende voorbeeld illustreert hoe u CullingGroups kunt gebruiken om meldingen te ontvangen op basis van het referentiepunt voor de afstand.
Dit script is vereenvoudigd voor de beknoptheid en maakt gebruik van verschillende krachtige methoden.
using UnityEngine;
using System.Linq;
public class CullingGroupBehaviour : MonoBehaviour
{
CullingGroup localCullingGroup;
MeshRenderer[] meshRenderers;
Transform[] meshTransforms;
BoundingSphere[] cullingPoints;
void OnEnable()
{
localCullingGroup = new CullingGroup();
meshRenderers = FindObjectsOfType<MeshRenderer>()
.Where((MeshRenderer m) => m.gameObject != this.gameObject)
.ToArray();
cullingPoints = new BoundingSphere[meshRenderers.Length];
meshTransforms = new Transform[meshRenderers.Length];
for (var i = 0; i < meshRenderers.Length; i++)
{
meshTransforms[i] = meshRenderers[i].GetComponent<Transform>();
cullingPoints[i].position = meshTransforms[i].position;
cullingPoints[i].radius = 4f;
}
localCullingGroup.onStateChanged = CullingEvent;
localCullingGroup.SetBoundingSpheres(cullingPoints);
localCullingGroup.SetBoundingDistances(new float[] { 0f, 5f });
localCullingGroup.SetDistanceReferencePoint(GetComponent<Transform>().position);
localCullingGroup.targetCamera = Camera.main;
}
void FixedUpdate()
{
localCullingGroup.SetDistanceReferencePoint(GetComponent<Transform>().position);
for (var i = 0; i < meshTransforms.Length; i++)
{
cullingPoints[i].position = meshTransforms[i].position;
}
}
void CullingEvent(CullingGroupEvent sphere)
{
Color newColor = Color.red;
if (sphere.currentDistance == 1) newColor = Color.blue;
if (sphere.currentDistance == 2) newColor = Color.white;
meshRenderers[sphere.index].material.color = newColor;
}
void OnDisable()
{
localCullingGroup.Dispose();
}
}
Voeg het script toe aan een GameObject (in dit geval een kubus) en druk op Spelen. Elke andere GameObject in scène verandert van kleur op basis van hun afstand tot het referentiepunt.
Zichtbaarheid van objecten verwijderen
Het volgende script illustreert hoe u gebeurtenissen kunt ontvangen op basis van de zichtbaarheid van een ingestelde camera.
Dit script maakt gebruik van verschillende prestaties zware methoden voor beknoptheid.
using UnityEngine;
using System.Linq;
public class CullingGroupCameraBehaviour : MonoBehaviour
{
CullingGroup localCullingGroup;
MeshRenderer[] meshRenderers;
void OnEnable()
{
localCullingGroup = new CullingGroup();
meshRenderers = FindObjectsOfType<MeshRenderer>()
.Where((MeshRenderer m) => m.gameObject != this.gameObject)
.ToArray();
BoundingSphere[] cullingPoints = new BoundingSphere[meshRenderers.Length];
Transform[] meshTransforms = new Transform[meshRenderers.Length];
for (var i = 0; i < meshRenderers.Length; i++)
{
meshTransforms[i] = meshRenderers[i].GetComponent<Transform>();
cullingPoints[i].position = meshTransforms[i].position;
cullingPoints[i].radius = 4f;
}
localCullingGroup.onStateChanged = CullingEvent;
localCullingGroup.SetBoundingSpheres(cullingPoints);
localCullingGroup.targetCamera = Camera.main;
}
void CullingEvent(CullingGroupEvent sphere)
{
meshRenderers[sphere.index].material.color = sphere.isVisible ? Color.red : Color.white;
}
void OnDisable()
{
localCullingGroup.Dispose();
}
}
Voeg het script toe aan de scène en druk op Afspelen. Alle geometrie in scène zal van kleur veranderen op basis van hun zichtbaarheid.
Een soortgelijk effect kan worden bereikt met de methode
MonoBehaviour.OnBecameVisible()
als het object een componentMeshRenderer
heeft. Gebruik CulingGroups wanneer u lege GameObjects,Vector3
coördinaten moet verwijderen of wanneer u een gecentraliseerde methode wilt om de zichtbaarheid van objecten te volgen.
Grenzende afstanden
U kunt grensafstanden bovenop de straal van het afbreekpunt toevoegen. Ze zijn op een manier extra trigger-omstandigheden buiten de hoofdradius van de ruimingspunten, zoals "dichtbij", "ver" of "zeer ver".
cullingGroup.SetBoundingDistances(new float[] { 0f, 10f, 100f});
Grenzende afstanden zijn alleen van invloed bij gebruik met een afstandsreferentiepunt. Ze hebben geen effect tijdens het ruimen van de camera.
Grensafstanden visualiseren
Wat aanvankelijk verwarring kan veroorzaken, is hoe grensafstanden bovenop de bolradius worden toegevoegd.
Eerst berekent de ruimgroep de oppervlakte van zowel de grensbol als de grensafstand. De twee gebieden worden bij elkaar opgeteld en het resultaat is het triggergebied voor de afstandsband. De straal van dit gebied kan worden gebruikt om het effectveld van de grensafstand te visualiseren.
float cullingPointArea = Mathf.PI * (cullingPointRadius * cullingPointRadius);
float boundingArea = Mathf.PI * (boundingDistance * boundingDistance);
float combinedRadius = Mathf.Sqrt((cullingPointArea + boundingArea) / Mathf.PI);