SceneKit SCNSceneRendererDelegate - renderer function not called

允我心安 提交于 2019-11-29 13:58:14

I suspect the answer hinges on what Querent means by "every frame". Querent should probably clarify this, but I'll try to answer anyway because I'm like that.

The simplest interpretation is probably "every frame that would render anyway", but that seems unlikely to be what is desired unless the cube is intended as a kind of activity monitor for the renderer, which doesn't seem likely either; there are much better approaches to that.

What Querent may want is to render repeatedly while the view's playing property is YES. If that's the case, then perhaps the answer is as simple as setting the view's loops property to YES. This recently solved a problem for me in which I wanted rendering to occur while a keyboard key was held down. (I had noticed that setting playing to YES would induce a single call to my delegate.)

Hal Mueller

I don't understand what's causing the problem, but I was able to replicate it. I got it to work, though, by adding a meaningless SCNAction:

let dummyAction = SCNAction.scaleBy(1.0, duration: 1.0)
let repeatAction = SCNAction.repeatActionForever(dummyAction)
cubeNode.runAction(repeatAction)

The render loop fires only if the scene is "playing" (see SKScene becomes unresponsive while being idle). I expect that setting

    sceneView.isPlaying = true

(as you're already doing) would be enough to trigger the render callbacks.

The code I have above is not a solution. It's a nasty hack to work around your problem and allow you to get on with life.

Entitize

For anyone still having problems, setting the delegate and playing variables will work.

sceneView.delegate = self
sceneView.isPlaying = true

In addition to several helpful hints in this chain, the final one for me to get delegate called was the following: If you use the pre Swift 4 methods for the SCNSceneRendererDelegate class, it compiles fine with no errors or warnings, but the delegate is never called.

Thus the obsolete pre-Swift 4 definition:

func renderer(aRenderer:SCNSceneRenderer, updateAtTime time:TimeInterval) {...}

(which I got from a snippet on the web) compiled just fine and was never called, while the correct definition

func renderer(_ renderer:SCNSceneRenderer, updateAtTimet time:TimeInterval) {...}

compiles and gets called!

Since SCNSceneRendererDelegate is a protocol, the normal Swift protections afforded by override are not appropriate. Since SCNSceneRendererDelegate defines its methods as optional (which I like), it is not caught that way either.

Try this…put your code in a scene class instead – keep the view controller clean.

final class MySCNScene:SCNScene, SCNSceneRendererDelegate
{
    @objc func renderer(aRenderer:SCNSceneRenderer, updateAtTime time:NSTimeInterval)
    {
    }
}

Also set the view's delegate to your scene:

mySCNView!.delegate = mySCNScene

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!