【问题标题】:Continuously rendering new child node objects on SceneKit scene in Swift在 Swift 中的 SceneKit 场景中不断渲染新的子节点对象
【发布时间】:2021-06-08 18:41:31
【问题描述】:

我有一个关于我正在做的 Scene Kit 项目的问题。所以我有这个场景,我随机生成立方体并将它们添加到我的场景根节点,问题是它们在开始时被渲染,但很快它们停止被渲染,所以我没有看到这些新对象被生成,我当我点击屏幕时会再次看到它们(所以当我在场景中做出动作或其他时)或者有时它们中的一些是随机渲染的,我不知道为什么

我尝试将 rendersContinuously 设置为 true,但这并没有改变任何东西。

这是立方体生成线程:

DispatchQueue.global(qos: .userInitiated).async {
            while true {
                self.spawnShape()
                sleep(1)
            }
 }

这是我将它们添加到子节点的方法:

let geometryNode = SCNNode(geometry: geometry)
geometryNode.simdWorldPosition = simd_float3(Float.random(in: -10..<10), 2, shipLocation+Float.random(in: 20..<30))

self.mainView.scene!.rootNode.addChildNode(geometryNode)

这是应用于相机和我的主节点的无尽动作:

ship.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: 0, z: 30, duration: 1)))
camera.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: 0, z: 30, duration: 1)))

除非我点击屏幕,否则添加的 geometryNode 立方体将停止渲染

即使我不触摸屏幕,如何在场景中强制渲染这些新的子节点对象?

谢谢

ZAY 询问的编辑:

这基本上是我的代码的开头:

    override func viewDidLoad() {
        super.viewDidLoad()
                
        guard let scene = SCNScene(named: "art.scnassets/ship.scn")
            else { fatalError("Unable to load scene file.") }

        let scnView = self.view as! SCNView
        self.mainView = scnView
        self.mainView.rendersContinuously = true
        
        self.ship = scene.rootNode.childNode(withName: "ship", recursively: true)!
        self.camera = scene.rootNode.childNode(withName: "camera", recursively: true)!
        
        self.ship.renderingOrder = 1
        
        self.ship.simdWorldPosition = simd_float3(0, 0, 0)
        self.camera.simdWorldPosition = simd_float3(0, 15, -35)
        
        self.mainView.scene = scene
        
        DispatchQueue.global(qos: .userInitiated).async {
            while true {
                self.spawnShape()
                sleep(1)
            }
        }
        
        ship.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: 0, z: 30, duration: 1)))
        camera.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: 0, z: 30, duration: 1)))
        
        let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.minimumPressDuration = 0
        self.mainView.addGestureRecognizer(tap)
    }

当我点击屏幕时,调用此代码:

    func tapHandler(gesture: UITapGestureRecognizer) {
        let p = gesture.location(in: self.mainView)
        let turnDuration: Double = 0.3
        print("x: \(p.x) y: \(p.y)")

        if gesture.state == .began {
            if p.x >= self.screenSize.width / 2 {
                self.delta = 0.5
            }
            else {
                self.delta = -0.5
            }
            self.ship.runAction(SCNAction.rotateBy(x: 0, y: 0, z: self.delta, duration: turnDuration))
            return
        }

        if gesture.state == .changed {
            return
        }

        self.ship.runAction(SCNAction.rotateBy(x: 0, y: 0, z: -self.delta, duration: turnDuration))
    }

基本上,它会根据我点击屏幕的哪一侧来向右或向左旋转我的船,它会显示我在控制台中点击的坐标。当我释放时,飞船会回到初始位置/旋转。

【问题讨论】:

  • 请提供更详细的代码。比如你如何启动你的主要功能等等......当你点击屏幕时你的代码会做什么等等。
  • 谢谢。我添加了一些信息。如果需要,我也可以上传屏幕截图。

标签: ios swift xcode scenekit scene


【解决方案1】:
DispatchQueue.global(qos: .userInitiated).async {
        while true {
            self.spawnShape()
            sleep(1)
        }
}

你这样做不是阻塞了共享队列吗?如果您想定期运行某些东西,请使用 Timer。

【讨论】:

  • 谢谢。我不知道为什么,但是使用 Timer 而不是这个 Queue + while true + sleep 解决了我的问题。
猜你喜欢
  • 2016-01-03
  • 2017-06-02
  • 2015-03-09
  • 2017-12-03
  • 1970-01-01
  • 2015-05-17
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多