【问题标题】:SCNSceneRendererDelegate - Renderer not being calledSCNSceneRendererDelegate - 未调用渲染器
【发布时间】:2020-09-02 05:19:13
【问题描述】:

在 Swift 游乐场中将委托设置为 SCNView 时,我的渲染器函数没有被调用。

我已经看过这个问题: SceneKit SCNSceneRendererDelegate - renderer function not called

该页面上的所有解决方案似乎都无法解决我的问题。我已经尝试过添加一个无意义的动画,启用isLooping,启用isPlaying,并确保渲染函数语法正确。

我完全不知道缺少什么,因为看似相同的代码被用作 PlaygroundBook 的一部分并且可以正常工作。提前谢谢。

import UIKit
import SceneKit
import PlaygroundSupport
import Foundation

class TestingRenderer: NSObject, SCNSceneRendererDelegate
{
    var tornadoCenter: SCNNode!
    let gameScene = SCNScene()
    var cameraNode: SCNNode!

    public func awakening()
    {
        cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()

        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 0)
        cameraNode.camera?.zFar = 200
        gameScene.rootNode.addChildNode(cameraNode)

        tornadoCenter = SCNNode()
        tornadoCenter.position = SCNVector3(x: 0, y: 0, z: 0)
        gameScene.rootNode.addChildNode(tornadoCenter)

// meaningless animation
        let animation = CABasicAnimation(keyPath: "rotation")
        animation.toValue = NSValue(scnVector4: SCNVector4(x: Float(0), y: Float(1), z: Float(0), w: Float.pi * 2))
        animation.duration = 30000
        animation.repeatCount = MAXFLOAT //repeat forever
        tornadoCenter.addAnimation(animation, forKey: nil)
    }

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
    {
        print("eeee")
    }

    func getScene() -> SCNScene
    {
        return gameScene
    }
}

class TestingView: SCNView
{
    public func setup()
    {
        let renderer = TestingRenderer()
        renderer.awakening()

        self.scene = renderer.getScene()
        self.backgroundColor = UIColor.black
        self.autoenablesDefaultLighting = true
        self.allowsCameraControl = true
        self.delegate = renderer
    }
}

class MyViewController : UIViewController
{
    var sceneView: TestingView!

    override func loadView()
    {
        let view = UIView()

        sceneView = TestingView()
        sceneView.setup()

        view.addSubview(sceneView)
        self.view = view
    }

    override func viewDidLayoutSubviews()
    {
        sceneView.frame = self.view.frame
    }
}

PlaygroundPage.current.liveView = MyViewController()

【问题讨论】:

    标签: swift xcode scenekit


    【解决方案1】:

    您需要使用 @objc attribute 使 SceneKit 可以看到委托方法。

    objc 属性告诉编译器有一个声明可用 在 Objective-C 代码中使用。

    @objc func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
    {
        print("eeee")
    }
    

    【讨论】:

    • 我添加了它,但没有改变。
    【解决方案2】:

    您需要保留对渲染器的引用,此时它会在设置函数返回后立即被释放。

    例如

    class TestingView: SCNView
    {
        let renderer = TestingRenderer()
    
        public func setup()
        {
            renderer.awakening()
    
            self.scene = renderer.getScene()
            self.backgroundColor = UIColor.black
            self.autoenablesDefaultLighting = true
            self.allowsCameraControl = true
            self.delegate = renderer
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-25
      • 2021-05-31
      • 1970-01-01
      • 2021-07-22
      • 2019-10-24
      • 1970-01-01
      • 2015-03-29
      • 2016-01-17
      • 1970-01-01
      相关资源
      最近更新 更多