ARKit与RealityKit Entity数量限制:生成的卡片数秒后消失如何解决
问题解答
关于单个AnchorEntity的子实体数量限制
RealityKit官方没有对单个AnchorEntity可挂载的子实体数量设置固定硬上限,实际可用数量取决于设备性能、实体的复杂程度(网格面数、材质数量)。你当前3排每排8张合计24张简单卡片的量级远未达到理论上限,问题和锚点的子实体数量限制无关。
卡片消失与报错的根因
你遇到的ARSessionDelegate is retaining 14 ARFrames报错和卡片消失问题,核心是两个代码错误导致的:
- 所有RealityKit/ARKit的场景操作(添加子实体、往场景中添加锚点等)必须在主线程执行,你当前把这部分逻辑放在后台全局队列同步执行,属于线程不安全操作,会导致ARFrame资源无法被正常释放,大量ARFrame被异常持有后ARKit会因为资源不足自动卸载你添加的锚点,卡片就会突然消失。
- 每个卡片单独重复生成相同的网格和材质,会造成不必要的内存占用,放大了资源不足的问题。
解决方案
1. 线程逻辑修正
把所有场景操作移到主线程执行,去掉后台队列的同步操作。
2. 资源复用优化
提前生成共享的卡片网格和材质,所有卡片实例复用同一份资源,降低内存开销。
修正后参考代码
// 提前创建共享的网格和材质,避免重复生成 private let sharedCardMesh = MeshResource.generateBox(width: 0.08, height: 0.01, depth: 0.08, cornerRadius: 0.005, splitFaces: false) private let sharedCardMaterial = SimpleMaterial(color: .red, isMetallic: false) func createCard(raycast: ARRaycastResult, maxrow: Int, cardPerRow: Int){ let anchor = AnchorEntity(raycastResult: raycast) var prPosMod = simd_make_float3(0,0,0) // prev position let cardByside = cardPerRow/2 // 所有场景操作放在主线程执行 DispatchQueue.main.async { for _ in 1...maxrow { for ncard in 1...cardPerRow { let modEntity = self.modelCard() if ncard < cardByside { modEntity.position = simd_make_float3(prPosMod.x-0.1,prPosMod.y,prPosMod.z) }else { modEntity.position = simd_make_float3(prPosMod.x + 0.1,prPosMod.y,prPosMod.z) } prPosMod = modEntity.position anchor.addChild(modEntity) } prPosMod = simd_float3(0,prPosMod.y,prPosMod.z-0.1) } self.arView.scene.addAnchor(anchor) } } func modelCard() -> ModelEntity { // 复用共享的网格和材质 return ModelEntity(mesh: sharedCardMesh, materials: [sharedCardMaterial]) }
可选扩展优化
如果后续需要生成上百张卡片,可以使用RealityKit的网格合并功能,把所有静态卡片的网格合并成单个ModelEntity,进一步降低Draw Call,提升渲染性能。
内容的提问来源于stack exchange,提问作者Damiano Miazzi
相关产品推荐
相关产品推荐

