AR应用崩溃报Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional如何解决
问题根因
- 你在
ContentView的按钮点击事件中直接调用arView.changeText,但当前作用域下没有定义arView变量,这是报错指向第18行的直接原因。 - 全局声明的隐式解包可选值
textEntity、planeAnchor从未被赋值:你在createPlane方法中定义了同名局部变量,赋值操作仅作用于局部变量,全局变量一直为nil,调用changeText时强制解包nil触发崩溃。 createPlane方法中锚点变量存在拼写错误:你写的planeAcnchor和全局变量planeAnchor拼写不一致,进一步导致全局变量无法被正确赋值。changeText方法中重复声明局部textEntity变量,修改操作不会同步到全局变量,后续调用依然会触发解包失败。changeText中重复将planeAnchor添加到场景,会产生锚点重复渲染的冗余问题。
修复步骤
- 声明全局ARView变量,在初始化ARView时给全局变量赋值,让按钮可以正常调用ARView的方法。
- 修正
createPlane方法中的变量拼写错误,取消局部变量声明,直接给全局的planeAnchor、textEntity赋值。 - 移除
changeText方法中重复的局部变量声明、重复添加锚点到场景的代码。
修复后完整代码
import SwiftUI import RealityKit import ARKit // 新增全局ARView变量,供按钮调用方法 var arView: ARView! var textElement = TextElements() var textEntity: ModelEntity! var planeAnchor: AnchorEntity! struct ContentView : View { var body: some View { return ARViewContainer() .overlay( VStack{ Spacer() Button(action:{ arView.changeText("Frank is awesome") }) { Text("Change Text") .frame(width:120,height:40) .font(.body) .foregroundColor(.black) .background(Color.white) .opacity(0.6) } .offset(y:-30) .padding(.bottom, 30) } ) .edgesIgnoringSafeArea(.all) } } struct ARViewContainer: UIViewRepresentable { func makeUIView(context: Context) -> ARView { // 给全局arView赋值 arView = ARView(frame: .zero) let config = ARWorldTrackingConfiguration() config.planeDetection = .horizontal arView.session.run(config, options: []) arView.session.delegate = arView arView.createPlane() return arView } func updateUIView(_ uiView: ARView, context: Context) {} } extension ARView: ARSessionDelegate { func createPlane() { // 修正拼写错误,直接给全局planeAnchor赋值,取消局部let声明 planeAnchor = AnchorEntity(plane: .horizontal) let textMesh: MeshResource = .generateText("Hello Frank!", extrusionDepth: textElement.extrusionDepth, font: textElement.font, containerFrame: CGRect(), alignment: .left, lineBreakMode: .byWordWrapping) let textMaterial = SimpleMaterial(color: textElement.textColor, isMetallic: true) // 直接给全局textEntity赋值,取消局部let声明 textEntity = ModelEntity(mesh: textMesh, materials: [textMaterial]) textEntity.generateCollisionShapes(recursive: false) planeAnchor.addChild(textEntity) self.scene.addAnchor(planeAnchor) self.installGestures(.all, for: textEntity) } func changeText(_ textContent: String) { let textMesh: MeshResource = .generateText(textContent, extrusionDepth: textElement.extrusionDepth, font: textElement.font, containerFrame: CGRect(), alignment: .left, lineBreakMode: .byWordWrapping) let textMaterial = SimpleMaterial(color: .blue, isMetallic: false) textEntity.removeFromParent() // 直接修改全局textEntity,不声明局部变量 textEntity = ModelEntity(mesh: textMesh, materials: [textMaterial]) planeAnchor.addChild(textEntity) // 移除重复添加锚点的冗余代码 self.installGestures(.all, for: textEntity) } } #if DEBUG struct ContentView_Previews : PreviewProvider { static var previews: some View { ContentView() } } #endif
内容的提问来源于stack exchange,提问作者Frank Lan
相关产品推荐
相关产品推荐

