You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:24:52