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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:20:45