首页 > 解决方案 > 没有调用 CullingGroup.onStateChanged

问题描述

我正在尝试使用 CullingGroup Api,但是我无法取得任何成功,因为看起来我的 onStateChanged 回调不会被调用。

我有 24 个球体和一个附有以下脚本的立方体。

using UnityEngine;

public class CullingGroupBehaviour : MonoBehaviour
{
    CullingGroup localCullingGroup;

    public Transform[] Spheres;
    public BoundingSphere[] cullingPoints;

    void Awake()
    {
        localCullingGroup = new CullingGroup();

        GameObject[] spheres = GameObject.FindGameObjectsWithTag("Spheres");
        cullingPoints = new BoundingSphere[spheres.Length];
        Spheres = new Transform[spheres.Length];

        for (var i = 0; i < spheres.Length; i++)
        {
            Spheres[i] = spheres[i].transform;
            cullingPoints[i].position = Spheres[i].position;
            cullingPoints[i].radius = 4.0f;
        }

        localCullingGroup.onStateChanged = (CullingGroupEvent evt) => Debug.Log("Changed");
        localCullingGroup.SetBoundingSpheres(cullingPoints);
        localCullingGroup.SetBoundingSphereCount(cullingPoints.Length);
        localCullingGroup.SetBoundingDistances(new float[] { 10.0f, 50.0f });
        localCullingGroup.SetDistanceReferencePoint(transform.position);
    }

    void FixedUpdate()
    {
        localCullingGroup.SetDistanceReferencePoint(transform.position);
        for (var i = 0; i < Spheres.Length; i++)
        {
            cullingPoints[i].position = Spheres[i].position;
        }
    }

    void OnDestroy()
    {
        localCullingGroup.Dispose();
        localCullingGroup = null;
    }
}

预期的行为是,当我移动立方体时,距离应该发生变化,并且应该调用 lambda 表达式但没有任何反应。任何想法表示赞赏!

更新:

奇怪的是,使用相机时可以正确发送可见性事件,但不会触发距离事件

标签: c#unity3d

解决方案


看起来您必须设置相机才能计算距离,这很奇怪,因为 DOC 说

如果指定了 targetCamera,则将仅从该相机的角度剔除边界球。

要让 CullingGroup 执行可见性计算,请指定它应该使用的相机

但是,当您不设置相机时,什么也没有发生。

附加说明:

onStateChnaged 事件只会在传递 BoundingDistance 时触发,例如:从 1 进入 2(示例仅包含一个)

工作解决方案:

using UnityEngine;

public class CullingGroupBehaviour : MonoBehaviour
{

    private CullingGroup cullingGroup;
    private BoundingSphere[] bounds;

    Transform[] targets;
    public Transform ReferencePoint;

    void Start()
    {
        // All the objects that have a sphere tag
        var gobjs = GameObject.FindGameObjectsWithTag("Sphere");
        targets = new Transform[gobjs.Length];
        for(int i = 0; i < gobjs.Length; i++)
        {
            targets[i] = gobjs[i].transform;
        }

        cullingGroup = new CullingGroup();

        cullingGroup.targetCamera = Camera.main;
        // Will automatically track the transform
        cullingGroup.SetDistanceReferencePoint(transform);
        // The distance points when the event will trigger
        cullingGroup.SetBoundingDistances(new float[] { 25.0f });
        // Creating Boundingspheres
        bounds = new BoundingSphere[targets.Length];
        for (int i = 0; i < bounds.Length; i++)
        {
            bounds[i].radius = 1.5f;
        }
        // Assigning the Bounding spheres
        cullingGroup.SetBoundingSpheres(bounds);
        // if not set it will use all of the array elements(so below code is redundant)
        cullingGroup.SetBoundingSphereCount(targets.Length);
        // Assigning an event when the distance changes
        cullingGroup.onStateChanged = OnChange;
    }

    void Update()
    {
        for (int i = 0; i < bounds.Length; i++)
        {
            bounds[i].position = targets[i].position;
        }
    }

    void OnDestroy()
    {
        cullingGroup.Dispose();
        cullingGroup = null;
    }

    void OnChange(CullingGroupEvent ev)
    {
        if (ev.currentDistance > 0)
        {
            targets[ev.index].gameObject.GetComponent<Renderer>().material.color = Color.green;
        }
        else
        {
            targets[ev.index].gameObject.GetComponent<Renderer>().material.color = Color.red;
        }
    }
}

推荐阅读