Sök…


Anmärkningar

Eftersom det inte alltid är så enkelt att använda CullingGroups kan det vara bra att hålla huvuddelen av logiken bakom en chefsklass.

Nedan följer en plan för hur en sådan chef kan fungera.

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);
}

Kärnan i det är att du reserverar en utskjutande sfär från chefen som returnerar indexet för den reserverade sfären. Du använder sedan det givna indexet för att manipulera din reserverade sfär.

Avstängning av föremål

Följande exempel illustrerar hur man använder CullingGroups för att få aviseringar enligt referenspunkten för avstånd.

Detta skript har förenklats för korthet och använder flera prestanda tunga metoder.

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();
    }
}

Lägg till skriptet till ett GameObject (i detta fall en kub) och tryck på Play. Varannan GameObject i scenen ändrar färg beroende på deras avstånd till referenspunkten.

ange bildbeskrivning här

Rullning av objektets synlighet

Följande skript illustrerar hur man tar emot händelser enligt synlighet för en inställd kamera.

Detta skript använder flera prestanda tunga metoder för korthet.

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();
    }
}

Lägg till skriptet till scenen och tryck på Play. All geometri i scenen kommer att ändra färg baserat på deras synlighet.

ange bildbeskrivning här

Liknande effekt kan uppnås med hjälp av MonoBehaviour.OnBecameVisible() om objektet har en MeshRenderer komponent. Använd CulingGroups när du behöver ta bort tomma GameObjects, Vector3 koordinater eller när du vill ha en centraliserad metod för att spåra objektets synlighet.

Begränsande avstånd

Du kan lägga till avståndsavgränsningar ovanpå radier för utspärringspunkten. De är på ett sätt ytterligare triggerförhållanden utanför utrotningspunkternas huvudradie, som "nära", "långt" eller "mycket långt".

cullingGroup.SetBoundingDistances(new float[] { 0f, 10f, 100f});

Begränsningsavstånd påverkas endast när de används med en referenspunkt för avstånd. De har ingen effekt under kameran.

Visualisera avgränsningsavstånd

Det som initialt kan orsaka förvirring är hur avgränsningsavstånd läggs ovanpå sfärradierna.

Först beräknar utrullningsgruppen arean för både avgränsningsfären och avgränsningsavståndet. De två områdena läggs samman, och resultatet är triggerområdet för distansbandet. Radien för detta område kan användas för att visualisera effektavgränsningsfältet.

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow