Unity八叉树开发:如何用C#指针数组存储子节点ABB引用?
问题描述
我正在Unity中开发八叉树,希望每个节点拥有指向子节点ABB的指针数组。ABB结构体定义如下:
public struct ABB { public float size; public float centerX; public float centerY; public float centerZ; public ABB(float size, float centerX, float centerY, float centerZ) { this.size = size; this.centerX = centerX; this.centerY = centerY; this.centerZ = centerZ; } }
每个节点包含子节点数组:
public OctreeNode[] children = null;
我需要在Burst Job中使用子节点的ABB,但OctreeNode是类,不被Burst支持。存储ABB副本冗余,因此想存储子节点ABB的指针。我定义了指针数组:
public ABB*[] childBounds = null;
尝试如下代码赋值时出现错误:
if (children[0] == null) { children[0] = new OctreeNode(new ABB(childLength, nodeBounds.centerX + -quarter, nodeBounds.centerY + quarter, nodeBounds.centerZ + -quarter), this, rootSeed); childBounds[0] = children[0].nodeBounds; }
错误提示:
Cannot implicitly convert type AABB (children[0].nodeBounds) to AABB*
请问在C#中如何正确实现指针数组的赋值?
解决方案
核心问题
children[0].nodeBounds是值类型(ABB是结构体),直接访问会返回副本,无法直接转为指针。要获取其内存地址,需要固定该字段的内存位置,避免GC移动导致指针失效。
正确赋值方式
使用fixed关键字固定nodeBounds的内存地址,再获取指针:
if (children[0] == null) { children[0] = new OctreeNode(new ABB(childLength, nodeBounds.centerX + -quarter, nodeBounds.centerY + quarter, nodeBounds.centerZ + -quarter), this, rootSeed); // 固定子节点nodeBounds的内存,获取指针 fixed (ABB* boundsPtr = &children[0].nodeBounds) { childBounds[0] = boundsPtr; } }
关键注意事项
- GC安全风险:OctreeNode是类,其对象在堆上的位置可能被GC移动,一旦移动,
childBounds中的指针就会失效。如果八叉树节点生命周期短或会被频繁GC,这种方式存在崩溃风险。 - Burst兼容性优化:Burst对非托管内存的支持更稳定,建议改用
NativeArray<ABB>存储所有边界,用整数索引代替指针——既避免指针安全问题,又完全符合Burst的使用规范:
这种方式性能不逊于指针,且无需担心GC问题,是Unity Burst开发的最佳实践。// 根节点或全局持有所有ABB的NativeArray public NativeArray<ABB> allBounds; // 子节点存储allBounds中的索引,而非指针 public int[] childBoundsIndices = null;
内容的提问来源于stack exchange,提问作者Hoogoo
相关产品推荐
相关产品推荐

