RealityKit:如何通过按钮移除最后添加的AnchorEntity
解决AR对象删除问题的方案
首先修正你原代码中的语法错误:updateUIView里的内层if let未闭合大括号,会导致编译失败,修正后代码如下:
func updateUIView(_ uiView: ARView, context: Context) { if let model = self.modelPlaced { if let modelEntity = model.modelEntity { let anchorEntity = AnchorEntity(plane: .any) let tempEntity = modelEntity.clone(recursive: true) anchorEntity.name = "EntityAnchor" anchorEntity.addChild(tempEntity) uiView.scene.addAnchor(anchorEntity) tempEntity.generateCollisionShapes(recursive: true) uiView.installGestures([.translation, .rotation, .scale], for: tempEntity) } // 补充内层if的闭合括号 DispatchQueue.main.async { self.modelPlaced = nil } } }
接下来解决删除最近放置对象的核心问题:你无法在DeleteButtonView中访问到updateUIView里创建的局部anchorEntity,需要通过共享状态管理来传递AR视图引用和最近放置的锚点。
步骤1:创建AR状态管理ViewModel
用ObservableObject统一管理AR相关状态,让AR视图和删除按钮能共享数据:
import ARKit import SwiftUI class ARViewModel: ObservableObject { @Published var arView: ARView? @Published var lastPlacedAnchor: AnchorEntity? @Published var isPlacementEnabled: Bool = false @Published var selectedModel: Model? @Published var modelPlaced: Model? }
步骤2:修改AR视图容器
将ViewModel传入UIViewRepresentable,在updateUIView中保存AR视图引用和最近放置的锚点:
struct ARViewContainer: UIViewRepresentable { @ObservedObject var viewModel: ARViewModel func makeUIView(context: Context) -> ARView { let arView = ARView(frame: .zero) viewModel.arView = arView return arView } func updateUIView(_ uiView: ARView, context: Context) { guard let model = viewModel.modelPlaced, let modelEntity = model.modelEntity else { return } let anchorEntity = AnchorEntity(plane: .any) let tempEntity = modelEntity.clone(recursive: true) anchorEntity.name = "EntityAnchor" anchorEntity.addChild(tempEntity) uiView.scene.addAnchor(anchorEntity) tempEntity.generateCollisionShapes(recursive: true) uiView.installGestures([.translation, .rotation, .scale], for: tempEntity) // 保存最近放置的锚点 viewModel.lastPlacedAnchor = anchorEntity DispatchQueue.main.async { viewModel.modelPlaced = nil } } }
步骤3:更新删除按钮视图
通过ViewModel获取AR视图和最近锚点,实现删除逻辑:
struct DeleteButtonView: View { @ObservedObject var viewModel: ARViewModel var body: some View { Button(action: { guard let arView = viewModel.arView, let lastAnchor = viewModel.lastPlacedAnchor else { return } // 移除最近放置的锚点 arView.scene.removeAnchor(lastAnchor) // 清空最近锚点记录 viewModel.lastPlacedAnchor = nil }) { Image(systemName: "xmark") .padding() .background(Color.red.opacity(0.8)) .foregroundColor(.white) .clipShape(Circle()) } } }
步骤4:主视图整合
在主视图中初始化ViewModel,将其传递给AR容器和删除按钮:
struct ContentView: View { @StateObject private var arViewModel = ARViewModel() var body: some View { ZStack { ARViewContainer(viewModel: arViewModel) VStack { Spacer() HStack { Spacer() DeleteButtonView(viewModel: arViewModel) .padding(.trailing, 20) } } } } }
这样点击删除按钮时,就会移除最近放置的AR对象,同时清空记录,确保下次删除的是新放置的对象。
内容的提问来源于stack exchange,提问作者JackSparrow135
相关产品推荐
相关产品推荐

