Я следил за учебником YouTube о том, как размещать виртуальные модели в SwiftUI.
Теперь, когда я могу разместить свои модели, я хотел бы сохранить и загрузить положение моделей.
Я уже сделал 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. Но из этого ничего не вышло. Я создал переменную состояния (тип Boolean), которая срабатывает, когда я нажимаю кнопку сохранения или загрузки. но я не могу правильно подключиться к функции 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, но будет истинным, когда я нажму соответствующие кнопки:
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)
}
}
}
}
Я пока не получаю сообщений об ошибках, но мой код, похоже, не работает. Я могу нажимать кнопки, но модели и якоря не перезагружаются после перезапуска приложения.