Buscar..


Observaciones

Dado que el uso de CullingGroups no siempre es muy sencillo, puede ser útil para encapsular la mayor parte de la lógica detrás de una clase de administrador.

A continuación se muestra un modelo de cómo podría operar un gerente de este tipo.

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

La esencia de esto es que usted reserva una esfera de selección del administrador que devuelve el índice de la esfera reservada. A continuación, utiliza el índice dado para manipular su esfera reservada.

Recoger distancias de objetos

El siguiente ejemplo ilustra cómo usar CullingGroups para obtener notificaciones de acuerdo con el punto de referencia de la distancia.

Esta secuencia de comandos se ha simplificado por motivos de brevedad y utiliza varios métodos pesados ​​de rendimiento.

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

Agrega el script a un GameObject (en este caso un cubo) y pulsa Play. Todos los demás GameObject en escena cambian de color de acuerdo con su distancia al punto de referencia.

introduzca la descripción de la imagen aquí

Visibilidad de objetos de selección

El siguiente script ilustra cómo recibir eventos según la visibilidad de una cámara establecida.

Este script utiliza varios métodos de rendimiento pesado para la brevedad.

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

Agrega el script a la escena y pulsa Play. Toda la geometría en escena cambiará de color en función de su visibilidad.

introduzca la descripción de la imagen aquí

Se puede lograr un efecto similar utilizando el método MonoBehaviour.OnBecameVisible() si el objeto tiene un componente MeshRenderer . Utilice CulingGroups cuando necesite seleccionar GameObjects vacíos, coordenadas Vector3 , o cuando desee un método centralizado de seguimiento de visibilidades de objetos.

Distancias delimitadas

Puede agregar distancias de límite en la parte superior del radio del punto de selección. Son, de alguna manera, condiciones de activación adicionales fuera del radio principal de los puntos de selección, como "cerca", "lejos" o "muy lejos".

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

Las distancias de límite afectan solo cuando se usan con un punto de referencia de distancia. No tienen efecto durante el sacrificio de la cámara.

Visualizando distancias de límite.

Lo que inicialmente puede causar confusión es cómo se agregan las distancias de los límites en la parte superior de los radios de la esfera.

Primero, el grupo de selección calcula el área de la esfera delimitadora y la distancia delimitadora. Las dos áreas se suman, y el resultado es el área de activación para la banda de distancia. El radio de esta área se puede utilizar para visualizar el campo de efecto de la distancia de delimitación.

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow