一、官网的Physics文档
https://docs.unity.cn/cn/2019.4/ScriptReference/Physics.html
1、Physics下带NonAlloc都是无GC的,项目中必须使用NonAlloc相关的函数来进行物理检测;
Physics.OverlapBox有GC,Physics.OverlapBoxNonAlloc无GC
二、Physics.NonAlloc的几个函数有时候生效有时候不生效问题
1、先看一下下面的测试代码
public class ColliderTest : MonoBehaviour
{
private Collider[] m_Colliders;
void Update()
{
m_Colliders = Physics.OverlapBox(Vector3.zero, new Vector3(2, 2, 2));
Debug.Log("OverlapBox:" + m_Colliders.Length);
var count = Physics.OverlapBoxNonAlloc(Vector3.zero, new Vector3(2, 2, 2), m_Colliders);
Debug.Log("OverlapBoxNonAlloc:" + count);
}
}
结果都可以
2、现在我们切换到项目中的无GC写法的代码中去
public class ColliderTest : MonoBehaviour
{
private Collider[] m_Colliders;
void Update()
{
var count = Physics.OverlapBoxNonAlloc(Vector3.zero, new Vector3(2, 2, 2), m_Colliders);
Debug.Log("OverlapBoxNonAlloc:" + count);
}
}
结果没有任何输出,失败了,为什么?
三、问题探究解决
1、我们看下两次代码都有哪些变化
(1)成功:测试代码的Physics.OverlapBox接收的Collider数组用的是m_Colliders
(2)成功:测试代码的Physics.OverlapBoxNonAlloc参数也是用的m_Colliders
(3)失败:测试代码的Physics.OverlapBoxNonAlloc参数是用的m_Colliders
2、发现问题所在
(1)成功:m_Colliders数组默认没有初始化,Physics.OverlapBox接收的数组赋值给了m_Colliders,此时m_Colliders就被初始化了,当Physics.OverlapBoxNonAlloc传递进去的数组就已经是初始化后的了,所以成功了;
(2)失败:m_Colliders数组没有被初始化,直接传递给了Physics.OverlapBoxNonAlloc的参数,Physics.OverlapBoxNonAlloc内部并不会对一个没有初始化的Collider[]进行初始化,因为Collider[]初始化的长度由外部使用者决定的,所以使用Physics.NonAlloc相关的函数外部传递进去的缓存数组必须先初始化
private Collider[] m_Colliders = new Collider[1];
2、问题解决
public class ColliderTest : MonoBehaviour
{
private Collider[] m_Colliders = new Collider[1];
void Update()
{
var count = Physics.OverlapBoxNonAlloc(Vector3.zero, new Vector3(2, 2, 2), m_Colliders);
Debug.Log("OverlapBoxNonAlloc:" + count);
}
}