如何在visionOS中使用RealityView创建带附件的实体?
动态为RealityKit生成的实体添加附件的解决方案
问题场景
有一个按钮,每次点击会生成新的立方体实体并作为根实体的子节点。需要给每个新生成的立方体都添加一个附件,但由于无法预知用户会生成多少实体,没法在初始化RealityView时提前定义所有可能的附件。
现有代码结构:
class ViewModel { var emptyRoot: Entity = Entity() func addCube() { let newCube = generateCube() emptyRoot.addChild(newCube) // 这里需要给newCube添加附件 } }
RealityView { content, attachments in // 初始加载空场景,此时没有实体 content.add(viewModel.emptyRoot) } update: { updateContent, updateAttachments in // 不确定这里怎么处理动态附件 } attachments: { // 按之前的认知,必须在这里定义所有附件并指定ID,但无法提前知道数量 }
解决方案
RealityKit支持动态创建附件ID,无需提前在attachments闭包中定义所有可能的附件。核心思路是为每个新生成的立方体分配唯一ID,通过绑定组件关联实体与附件,再利用响应式数据驱动附件视图的动态生成。
1. 修改ViewModel,管理实体与附件ID的关联
class ViewModel: ObservableObject { var emptyRoot: Entity = Entity() // 存储实体与对应附件ID的映射,@Published驱动视图更新 @Published var cubeAttachmentMap: [Entity: String] = [:] func addCube() { let newCube = generateCube() emptyRoot.addChild(newCube) // 生成唯一附件ID let uniqueAttachmentID = UUID().uuidString cubeAttachmentMap[newCube] = uniqueAttachmentID // 给实体添加附件绑定组件,关联到对应的ID newCube.components.set(AttachmentComponent(id: uniqueAttachmentID, parentAnchor: newCube)) } private func generateCube() -> Entity { let cube = ModelEntity(mesh: .generateBox(size: 0.1)) cube.position = SIMD3<Float>(.random(in: -0.5...0.5), .random(in: -0.5...0.5), .random(in: -0.5...0.5)) return cube } }
2. 在RealityView中动态生成附件视图
利用ForEach遍历ViewModel中的附件ID,为每个ID创建对应的附件视图:
struct ContentView: View { @StateObject private var viewModel = ViewModel() var body: some View { VStack { Button("添加立方体") { viewModel.addCube() } .padding() RealityView { content, attachments in content.add(viewModel.emptyRoot) } update: { _, _ in // 无需额外操作,附件视图会随ID列表自动更新 } attachments: { ForEach(Array(viewModel.cubeAttachmentMap.values), id: \.self) { attachmentID in Attachment(id: attachmentID) { // 自定义附件视图,这里示例为带背景的文本标签 Text("立方体\(attachmentID.prefix(5))") .font(.caption) .padding(4) .background(Color.white.opacity(0.8)) .cornerRadius(4) } } } } } }
关键说明
- 唯一ID生成:通过
UUID()保证每个附件拥有独立标识,避免冲突 - AttachmentComponent:将实体与附件ID绑定,让RealityKit能找到对应附件视图
- 响应式更新:
@Published修饰的cubeAttachmentMap会触发attachments闭包自动更新,生成新的附件视图 - 无需预定义:完全支持动态生成任意数量的实体和对应附件,无需提前预知数量
内容的提问来源于stack exchange,提问作者Gerry Gao
相关产品推荐
相关产品推荐

