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.

voer hier de afbeeldingsbeschrijving in

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.

voer hier de afbeeldingsbeschrijving in

Een soortgelijk effect kan worden bereikt met de methode MonoBehaviour.OnBecameVisible() als het object een component MeshRenderer 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);


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow