【发布时间】:2020-12-23 02:23:53
【问题描述】:
我遵循了关于如何在 SwiftUI 中放置虚拟模型的 YouTube 教程。
现在我可以放置模型了,我想保存并加载模型位置。
我已经制作了 2 个用于保存和加载的按钮,但我不知道保存和加载实体和锚点的正确代码。
以下代码在我的 updateUIView 函数中:
func updateUIView(_ uiView: ARView, context: Context) {
if let name = self.modelName {
print("Modell mit dem Namen \(name) wurde zum plaziert")
let filename = name + ".usdz"
let modelEntity = try! ModelEntity.loadModel(named: filename)
modelEntity.generateCollisionShapes(recursive: true)
uiView.installGestures(.all, for: modelEntity)
let anchorEntity = AnchorEntity(plane: .any)
anchorEntity.addChild(modelEntity)
uiView.scene.addAnchor(anchorEntity)
}
}
我尝试使用“else”语句,因为我一开始就有“if”。但这没有成功。我创建了一个状态变量(布尔类型),当我按下保存或加载按钮时触发。但我无法正确连接到 updateUIView 函数。
更新 1:
我在“updateUIView”函数中实现了保存和加载函数,如下所示:
struct ARViewContainer: UIViewRepresentable {
@Binding var reset: Bool
@Binding var modelSelector: String
@Binding var save: Bool
@Binding var load: Bool
let config = ARWorldTrackingConfiguration()
func makeUIView(context: Context) -> ARView {
// create config for all entities
let arView = ARView(frame: .zero)
config.planeDetection = [.horizontal, .vertical]
config.environmentTexturing = .automatic
config.sceneReconstruction = .mesh
arView.session.run(config)
return arView
}
// App kontinuierlich beobachten
func updateUIView(_ uiView: ARView, context: Context) {
// create anchor and model-Entity
if modelSelector != "default" {
let modelEntity = try! ModelEntity.loadModel(named: "\(modelSelector)")
modelEntity.name = ("\(modelSelector)")
modelEntity.generateCollisionShapes(recursive: true)
uiView.installGestures(.all, for: modelEntity)
let anchor = AnchorEntity(plane: .any)
anchor.addChild(modelEntity)
uiView.scene.addAnchor(anchor)
}
// reset anchor
if reset == true {
uiView.scene.anchors.removeAll()
}
//MARK: saveload
if save == true {
uiView.session.getCurrentWorldMap { (worldMap, _) in
if let map: ARWorldMap = worldMap {
let data = try! NSKeyedArchiver.archivedData(withRootObject: map,
requiringSecureCoding: true)
let savedMap = UserDefaults.standard
savedMap.set(data, forKey: "WorldMap")
savedMap.synchronize()
}
}
}
if load == true {
let storedData = UserDefaults.standard
if let data = storedData.data(forKey: "WorldMap") {
if let unarchiver = try? NSKeyedUnarchiver.unarchivedObject(
ofClasses: [ARWorldMap.classForKeyedUnarchiver()],
from: data),
let worldMap = unarchiver as? ARWorldMap {
config.initialWorldMap = worldMap
uiView.session.run(config)
}
}
}
//MARK:
}
}
通过将代码直接写入 updateUIView 函数,我可以使用 uiView 而不是 arView。只有配置常量必须在 makrUIView 函数之外。 加载和保存的布尔值设置为 false,但当我按下相应的按钮时将为 true:
struct SaveLoadReset: View {
@Binding var reset: Bool
@Binding var save: Bool
@Binding var load: Bool
@Binding var modelSelector: String
var body: some View {
//HStack für den Laden und Speichern Knopf
HStack(spacing: 10){
//save-Button:
Button(action: {
print("DEBUG: saveButton")
self.modelSelector = "default"
self.save = true
print("DEBUG: save = \(self.save)")
})
{
Image(systemName: "square.and.arrow.up")
.padding(20)
.background(Color.white)
.opacity(0.3)
.cornerRadius(20)
.padding(10)
.font(.title)
}
//load-Button:
Button(action: {
print("DEBUG: loadButton")
self.load = true
print("DEBUG: load = \(self.load)")
})
{
Image(systemName: "square.and.arrow.down")
.padding(20)
.background(Color.white)
.opacity(0.3)
.cornerRadius(20)
.font(.title)
}
Spacer()
//reset-Button:
Button(action: {
print("DEBUG: removeButton")
self.reset = true
print("DEBUG: reset = \(self.reset)" )
})
{
Image(systemName: "arrow.clockwise.circle")
.padding(20)
.background(Color.white)
.opacity(0.3)
.cornerRadius(20)
.font(.title)
.padding(10)
}
}
}
}
到目前为止,我没有收到任何错误消息,但我的代码似乎不起作用。 我可以按下按钮,但重新启动应用后模型和锚点不会重新加载。
【问题讨论】:
-
看看这篇文章中的第五种方法 - stackoverflow.com/questions/56900601/…
-
所以我只使用按钮内的写入和加载功能?还是在 ARViewContainer 结构内部?
标签: swiftui augmented-reality arkit realitykit arworldmap