CullingGroup API的使用说明

最近一直在学习Unity的官方文档,今天看到CullingGroup API,按官方文档的话,它提供了将自己的处理方式集成到Unity的剔除和LOD管道中去。

感觉文档讲得不是很清楚,我看网上的资料也不多,于是翻看了API说明,自己研究了一下用法


CullingGroup不是可视化组件,所以在使用时需要自己new 一个:

CullingGroup group = new CullingGroup();



首先你需要提供给CullingGroup一组BoundingSphere(我叫它包围球 ):

BoundingSphere[] spheres = new BoundingSphere[1000];// 为什么要1000个,后面说

spheres[0] = new BoundingSphere(Vector3.zero, 1f);// 位置和半径,用几个new几个

group.SetBoundingSpheres(spheres);// 将数组的引用提供给CullingGroup

group.SetBoundingSphereCount(1);// 确切的告诉CullingGroup,你到底使用了几个包围盒


CullingGroup主要功能,就是高效的计算,这组包围球 是否被在指定摄像机 观察到了,以及与某个参考点的位置距离关系

你把包围球 包在你所关心的对象上,类似包个碰撞盒(但CullingGroup目前只支持球体)

当某个包围球体 对于指定摄像机 的可见状态发现改变,或者 它进入或者离开参考点的某个距离范围时,CullingGroup会通知你,然后你可以对其包围的游戏对象进行自己的处理或者优化。


group.onStateChanged = StateChangedMethod;// 设置回调  上述状态发现改变时通知

group.targetCamera = Camera.main;// 设置指定的摄像机


group.SetDistanceReferencePoint (Camera.main.transform);// 设置参考点

group.SetBoundingDistances (new float[]{ 5f, 10f, 20f });// 设置参考距离 类似LOD的level绑定距离


	// 通知回调
	private void StateChangedMethod(CullingGroupEvent evt)
	{
		if (evt.hasBecomeVisible) {		// 当某个包围球变得可见时
			Debug.LogFormat("Sphere {0} has become visible!", evt.index);
			return;
		}
			
		if (evt.hasBecomeInvisible) {	// 当某个包围球变得不可见时
			Debug.LogFormat("Sphere {0} has become invisible!", evt.index);
			return;
		}
			
		if (evt.currentDistance != evt.previousDistance) {	// 当某个包围球进入参考点的某个绑定距离范围
			Debug.LogFormat("Sphere {0} has enter distance band {1}!", evt.index, evt.currentDistance);
			return;
		}
	}


CullingGroup只能告诉你,某个包围球是否可见,或者在某个距离范围内,而不能告诉它到底距离是多少

bool sphereIsVisible = group.IsVisible(0);

int sphereDistanceBand = group.GetDistance(0);


你可以使用 QueryIndices 方法,获取包围球中到底有多少,有哪些是可见的,或者在某个距离范围,诸如此类


// 返回满足条件的包围球的index
int[] resultIndices = new int[1000];
// 返回满足条件的包围球的总数
int numResults = 0;

// 查询所有可见的包围球
numResults = group.QueryIndices(true, resultIndices, 0);
// 查询所有绑定距离范围1的包围球
numResults = group.QueryIndices(1, resultIndices, 0);
// 查询所有不可见,且在绑定距离范围2的包围球, 并且忽略前100个
numResults = group.QueryIndices(false, 2, resultIndices, 100);


来说说,为什么要包围球数组元素是1000,因为包围球数组允许你随时改变包围球的使用数量,而数组的元素个数是不能改变的,所以一开始尽量设大一点,要够用。

当有多个CullingGroup对象时,也可以共用一个包围球数组,这样其实更效率。CullingGroup是直接使用引用所指向的数据,所以要保证BoundingSphereCount的正确性


不使用CullingGroup时,记得要是释放:

group.Dispose();

group = null;


应用场景:

一、可视性检测的应用


比如检测主角是否被敌人发现,可以给敌人头部位置挂上摄像机组件,然后给主角包上包围,为了时结果更精确,可以给主角模型上下各设一个包围球甚至更多,然后检测所有包围球的可见性,有一个可见即被敌人发现(当然这个应用场景我想出来的。。)

CullingGroup的可见性的依据,是摄像机的视椎体剔除和静态阻挡剔除,对动态物体的阻挡情况无法检测


二、距离范围检测的应用

这个应用感觉会比较多一点

比如根据与主摄像机距离范围,远的角色可以不绘制,或者不使用高质量动画,降低AI程度,这完全类似LOD技术,但是可以自由的按自己的方式来处理,对性能优化是不错的选择。

比如在一大堆游戏对象中找到距离参考点一米范围内的对象。


展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读