Hi! I am using culling group api and have some problems. I have a line of cubes. Camera moving along this line. When a cube is visible it has green color, else red color. While the camera moving it remove cubes. If the camera only moving without deleting - all visible cubes are green. With deleting some cubes are red. Code (CSharp): using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class RenderManager : MonoBehaviour { private Camera _camera; private InstancedDrawObject[] items; public GameObject prefab; private Vector3 pos; private Vector3 increment; private CullingGroup cullingGroup; private int usedBoundingSphereCount; private BoundingSphere[] boundingSphere; private InstancedDrawObject[] drawInstances; const int maxInstances = 250; private void Awake() { _camera = Camera.main; drawInstances = new InstancedDrawObject[maxInstances]; boundingSphere = new BoundingSphere[maxInstances]; InitializeCullingGroup(); InitializeItems(); } private void InitializeItems() { increment = new Vector3(50, 0, 0); items = new InstancedDrawObject[maxInstances]; int z = 35; for (int x = 0; x < maxInstances; ++x) { GameObject gameObject = Instantiate(prefab); InstancedDrawObject instancedDrawObject = gameObject.GetComponent<InstancedDrawObject>(); instancedDrawObject.position = new Vector3(x, 0, z); items[x] = instancedDrawObject; AddInstance(instancedDrawObject); } pos = new Vector3(0, 0, z); } private void InitializeCullingGroup() { cullingGroup = new CullingGroup(); cullingGroup.targetCamera = _camera; cullingGroup.onStateChanged = CullingStateChanged; cullingGroup.SetBoundingSpheres(boundingSphere); usedBoundingSphereCount = 0; cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount); } private void CullingStateChanged(CullingGroupEvent evt) { drawInstances[evt.index].visible = evt.isVisible; } public void AddInstance(InstancedDrawObject instance) { drawInstances[usedBoundingSphereCount] = instance; boundingSphere[usedBoundingSphereCount].position = instance.position; boundingSphere[usedBoundingSphereCount].radius = instance.radius; ++usedBoundingSphereCount; cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount); instance.visible = cullingGroup.IsVisible(usedBoundingSphereCount - 1); } public void RemoveInstance(InstancedDrawObject instancedDrawObject) { int foundIndex = -1; for (int i = 0; i < usedBoundingSphereCount; ++i) { if (drawInstances[i] == instancedDrawObject) { foundIndex = i; break; } } if (foundIndex == -1) { return; } for (int i = foundIndex; i < usedBoundingSphereCount - 1; ++i) { drawInstances[i] = drawInstances[i + 1]; boundingSphere[i] = boundingSphere[i + 1]; } for (int i = usedBoundingSphereCount; i < drawInstances.Length; ++i) { //drawInstances[i] = null; //boundingSphere[i] = new BoundingSphere(); } //Array.Copy(drawInstances, foundIndex + 1, drawInstances, foundIndex, usedBoundingSphereCount - foundIndex - 1); --usedBoundingSphereCount; cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount); DestroyImmediate(instancedDrawObject.gameObject); } private void Update() { int x = (int)(pos.x); if (x < items.Length) { InstancedDrawObject drawObject = items[x]; if (drawObject != null) { RemoveInstance(drawObject); items[x] = null; } } pos += increment * Time.deltaTime; _camera.transform.position += increment * Time.deltaTime; } private void OnDestroy() { cullingGroup.Dispose(); cullingGroup = null; } }
Have you tried setting bounding sphere reference array again in RemoveInstance? E.g. Code (CSharp): --usedBoundingSphereCount; cullingGroup.SetBoundingSpheres(boundingSphere); cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount); DestroyImmediate(instancedDrawObject.gameObject); I had simillar issues with culling group not updating array data properly when only setting the count. Might be worth trying. Alternatively, make sure you're adding / removing correct instances of the objects.
I have tried but the result is the same. I found this method CullingGroup.EraseSwapBack and it probably works. Code (CSharp): public void RemoveInstance(InstancedDrawObject instancedDrawObject) { int foundIndex = -1; for (int i = 0; i < usedBoundingSphereCount; ++i) { if (drawInstances[i] == instancedDrawObject) { foundIndex = i; break; } } if (foundIndex == -1) { return; } drawInstances[foundIndex] = drawInstances[usedBoundingSphereCount - 1]; cullingGroup.EraseSwapBack(foundIndex); --usedBoundingSphereCount; cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount); DestroyImmediate(instancedDrawObject.gameObject); }