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

SceneKit中SCNTransaction在场景加载时不执行,需点击屏幕后才生效的问题求助

SceneKit中SCNTransaction在场景加载时不执行,需点击屏幕后才生效的问题求助

大家好,我正在用代码创建SceneKit场景,想通过下面的方法让相机聚焦到我添加的所有节点上,并且用SCNTransaction包裹来实现平滑的移动动画:

@objc
func resetCamera() {
    SCNTransaction.begin()
    SCNTransaction.animationDuration = 0.5
    
    sceneView.defaultCameraController.stopInertia()
    sceneView.defaultCameraController.frameNodes(annotationRootNode?.childNodes ?? [])
    
    SCNTransaction.commit()
}

这个动画运行起来效果很好,但问题是初始加载场景时这段代码完全不生效,必须手动点击屏幕之后才能正常执行。有没有大佬能帮忙看看问题出在哪?


我已经尝试过这些方案,但都没能解决问题:

  • 把resetCamera()放在viewDidAppear里执行,或者用dispatchQueue异步/同步调度执行
  • 手动开启SceneView的isPlaying = true属性
  • 谷歌、开发者论坛、ChatGPT、Stack Overflow都搜了一圈,没找到类似的问题解决方案

我的SceneView设置代码:

func setupViews() {
    ...
    view.addSubview(viewContainer)
    viewContainer.addSubview(sceneView)
    
    viewContainer.snp.makeConstraints { make in
        make.edges.equalTo(view.safeAreaLayoutGuide).inset(Constants.defaultInset)
    }
    
    sceneView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
    }
    
    sceneView.scene = scene
    sceneView.delegate = self
    sceneView.overlaySKScene = annotationScene
    
    sceneView.defaultCameraController.automaticTarget = true
    sceneView.defaultCameraController.delegate = self
    sceneView.defaultCameraController.inertiaEnabled = false
    
    camera.usesOrthographicProjection = true
    camera.orthographicScale = 10.0
    cameraNode.camera = camera
    cameraNode.eulerAngles = SCNVector3(-45.0 * .pi / 180, 45.0 * .pi / 180.0, .zero)
    sceneView.pointOfView = cameraNode        
    sceneView.backgroundColor = .clear
    sceneView.allowsCameraControl = true
    ...
}

我的场景节点加载代码:

func loadAnnotations(with nodes: [NodesData]) {
    annotationRootNode = SCNNode()
    for node in nodes {
        let geometry: SCNGeometry = SCNSphere(radius: 1.0)
        let child: SCNNode = SCNNode(geometry: geometry)
        child.name = node.name
        child.position = node.position
        child.position.y = Float(node.level) * 5.0
        
        if levelNodesDict[node.level] == nil {
            let currLevelNode: SCNNode = SCNNode()
            currLevelNode.addChildNode(child)
            levelNodesDict[node.level] = currLevelNode
        }
        else {
            levelNodesDict[node.level]?.addChildNode(child)
        }
    }
    
    for node in levelNodesDict.values {
        annotationRootNode?.addChildNode(node)
    }
    
    if let annotationRootNode {
        scene.rootNode.addChildNode(annotationRootNode)
        scene.rootNode.worldPosition = .init(x: .zero, y: .zero, z: .zero)
    }
}

备注:内容来源于stack exchange,提问作者Yahya Ayyash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 08:39:31