ARKit加载多个usdz模型文件并点击切换显示,解决切换卡顿

实现效果如上所示,可以点击模型切换显示,加入了特征点显示的debugOptions,所以界面上会显示很多特征点。刚开始的时候,因为没有预加载模型文件,导致点击切换的时候再加载,就会出现卡顿一下的现象,所以做了优化处理,程序刚启动,就加载所有的模型文件,后续切换就很顺畅了。

1.先在官网下载模型文件并导入到xcode中

2.运行代码

Swift 复制代码
import ARKit
import RealityKit
import SwiftUI

struct ContentView: View {
    let modelName = ["biplane", "drummertoy", "pancakes", "pegasus"]
    var modelMap: [String: ModelEntity] = [:]

    @State private var curModel: ModelEntity

    init() {
        print("init app")
        for model in modelName {
            let modelEntry = try! ModelEntity.loadModel(named: "\(model).usdz")
            self.modelMap[model] = modelEntry
        }
        self.curModel = self.modelMap[self.modelName.first!]!
    }

    var body: some View {
        VStack {
            ARViewContainer(curModel: $curModel)
            HStack {
                ForEach(modelName, id: \.self) {
                    model in
                    Image(model).resizable().frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/).onTapGesture {
                        print("click model: \(model)")
                        // 更新当前模型
                        curModel = self.modelMap[model]!
                    }
                }
            }.padding(.horizontal)
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var curModel: ModelEntity

    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        arView.debugOptions = .showFeaturePoints

        // 配置 AR 会话,启用平面检测
        let configuration = ARWorldTrackingConfiguration()
        // 启用水平面检测
        configuration.planeDetection = [.horizontal]
        arView.session.run(configuration)

        // 创建一个水平面锚点
        let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2)))

        // 加载usdz模型文件
        let modelEntry = curModel
        modelEntry.position = [0, 0, 0]
        modelEntry.scale = [0.01, 0.01, 0.01]
        anchor.addChild(modelEntry)

        // 创建一个灯光
        let light = PointLight()
        light.position = [0, 1, 0]
        anchor.addChild(light)

        // 将锚点添加到场景中
        arView.scene.anchors.append(anchor)

        // 添加触摸事件识别器
        let tapGestureRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap(_:)))
        // 给arview添加动作识别
        arView.addGestureRecognizer(tapGestureRecognizer)

        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {
        print("update ui view")
        // 删除之前的模型
        uiView.scene.anchors.removeAll()
        // 更新模型
        let modelEntry = curModel
        modelEntry.position = [0, 0, 0]
        modelEntry.scale = [0.01, 0.01, 0.01]
        let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2)))
        anchor.addChild(modelEntry)
        uiView.scene.anchors.append(anchor)
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
}
相关推荐
练习时长一年4 小时前
LeetCode热题100(分割等和子集)
算法·leetcode·职场和发展
橘颂TA7 小时前
【剑斩OFFER】算法的暴力美学——力扣 130 题:被围绕的区域
算法·leetcode·职场和发展·结构与算法
a努力。8 小时前
宇树Java面试被问:数据库死锁检测和自动回滚机制
java·数据库·elasticsearch·面试·职场和发展·rpc·jenkins
Tisfy9 小时前
LeetCode 1292.元素和小于等于阈值的正方形的最大边长:二维前缀和(无需二分)+抽象速懂的描述
算法·leetcode·职场和发展
期末考复习中,蓝桥杯都没时间学了10 小时前
力扣刷题记录2
算法·leetcode·职场和发展
天真小巫11 小时前
2026.1.19总结
职场和发展
Dream it possible!12 小时前
蓝桥杯_工作时长_C++
c++·蓝桥杯·竞赛
敲敲了个代码12 小时前
UniApp 的 rpx是什么,跟rem比呢?
前端·javascript·面试·职场和发展·微信小程序·uni-app
wuqingshun31415912 小时前
蓝桥杯 云神的子数组和
算法·蓝桥杯·图论
橘颂TA12 小时前
【剑斩OFFER】算法的暴力美学——力扣 695 题:岛屿的最大面积
算法·leetcode·职场和发展