Recherche…


Remarques

Comme l'utilisation de CullingGroups n'est pas toujours simple, il peut être utile d'encapsuler l'essentiel de la logique derrière une classe de gestionnaire.

Vous trouverez ci-dessous un schéma de fonctionnement d'un tel gestionnaire.

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

L'essentiel est que vous réserviez une sphère d'abattage du gestionnaire qui renvoie l'index de la sphère réservée. Vous utilisez ensuite l'index donné pour manipuler votre sphère réservée.

Culling object distances

L'exemple suivant montre comment utiliser CullingGroups pour obtenir des notifications en fonction du point de référence de distance.

Ce script a été simplifié pour plus de brièveté et utilise plusieurs méthodes très performantes.

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

Ajoutez le script à un GameObject (dans ce cas un cube) et appuyez sur Play. Tous les autres GameObject en scène changent de couleur en fonction de leur distance par rapport au point de référence.

entrer la description de l'image ici

Suppression de la visibilité des objets

Le script suivant illustre comment recevoir des événements en fonction de la visibilité sur une caméra définie.

Ce script utilise plusieurs méthodes performantes pour des raisons de brièveté.

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

Ajoutez le script à la scène et appuyez sur Play. Toute la géométrie en scène changera de couleur en fonction de leur visibilité.

entrer la description de l'image ici

Un effet similaire peut être obtenu à l'aide de la méthode MonoBehaviour.OnBecameVisible() si l'objet possède un composant MeshRenderer . Utilisez CulingGroups lorsque vous devez Vector3 coordonnées GameObjects, Vector3 vides ou une méthode centralisée de suivi des visibilités d'objet.

Distances limites

Vous pouvez ajouter des distances limites au-dessus du rayon du point de réforme. Ils sont en quelque sorte des conditions de déclenchement supplémentaires en dehors du rayon principal des points d'abattage, comme "fermer", "loin" ou "très loin".

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

Les distances limites affectent uniquement l'utilisation d'un point de référence de distance. Ils n'ont aucun effet lors de l'abattage de l'appareil photo.

Visualiser les distances limites

Ce qui peut causer une confusion initiale est la façon dont les distances limites sont ajoutées au-dessus des rayons de la sphère.

Tout d'abord, le groupe de sélection calcule l' aire de la sphère de délimitation et de la distance limite. Les deux zones sont additionnées et le résultat est la zone de déclenchement de la bande de distance. Le rayon de cette zone peut être utilisé pour visualiser le champ d’effet de la distance limite.

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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow