Swift 如何使用SCNNodeRenderDelegate?

Swift 如何使用SCNNodeRenderDelegate?,swift,scenekit,Swift,Scenekit,我是Swift和SceneKit的新手,正在尝试了解如何使用SCNNoderenderDelegate 我宣布代表如下 class MyRender: NSObject, SCNNodeRendererDelegate { func renderNode(node: SCNNode, renderer: SCNRenderer, arguments: [NSObject : AnyObject]) { node.rendererDelegate!.renderNode!(node,

我是Swift和SceneKit的新手,正在尝试了解如何使用SCNNoderenderDelegate

我宣布代表如下

class MyRender: NSObject, SCNNodeRendererDelegate {

  func renderNode(node: SCNNode, renderer: SCNRenderer, arguments: [NSObject : AnyObject]) {
    node.rendererDelegate!.renderNode!(node, renderer: renderer, arguments: arguments)
  }
}
并尝试使用它

class GameViewController: NSViewController {

  @IBOutlet weak var gameView: GameView!

  override func awakeFromNib(){
    // ... some code ....
    let boxNode = SCNNode()
    boxNode.geometry = SCNBox(width: 5, height: 5, length: 5, chamferRadius: 0.1)
    boxNode.geometry?.firstMaterial?.diffuse.contents = NSColor.blueColor()
    boxNode.rendererDelegate = MyRender()
    scene.rootNode.addChildNode(boxNode)
    // ... some code ....
启动后,由于EXC\u访问错误而失败(代码=1,地址=0x0)
请帮助我理解,我做错了什么。

我可以看到三个问题:

  • 委托不会被保留,因此您必须通过将
    MyRender
    实例赋给某个强变量(例如实例变量)来保持其活动状态

  • renderDelegate
    被声明为
    assign
    而不是
    ,因此当委托被解除分配时,它不会自动设置为
    nil
    (这是SceneKit中的一个弱点),因此您必须显式地将其设置为
    nil
    。这里,当
    MyRender
    实例被解除分配场景时,它仍然认为
    boxNode
    有一个委托,并向解除分配的对象发送消息(EXC\u BAD\u访问崩溃)

  • 看起来你会在一个无限循环中结束。您的委托方法正在调用自身


  • 首先,你必须定义你的类

     @interface YourClass : SCNView <SCNPhysicsContactDelegate, SCNSceneRendererDelegate>
     {
    
     }
     @end
    
    您可以在初始化类时这样做,我个人将Myscene和MYview打包为一个单例

    完成所有这些操作后,在实现文件中添加以下行:

    pragma标记物理删除门 pragma-mark-renderelegate
    -(void)渲染器:(id)aRenderer UpdateAtime:(NSTimeInterval)时间{
    -(void)渲染器:(id)aRenderer didApplyAnimationsAtTime:(NSTimeInterval)时间{
    -(void)渲染器:(id)Arenderr didRenderScene:(SCNScene*)场景时间:(NSTimeInterval)时间{
    -(void)渲染器:(id)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)时间{}
    -(void)渲染器:(id)arender willRenderScene:(SCNScene*)场景时间:(NSTimeInterval)时间{
    
    现在,您可以参与渲染和物理代理

    当然,Pragma标记不是必需的。
    希望这对您有所帮助

    您试图使用节点渲染器代理做什么?正如到目前为止的答案中所指出的,到目前为止您所拥有的代码是毫无意义的。@rickster在本例中,我试图使渲染器委托为“空”,但由于mnuages提到的原因,它失败了。我想将它用于自定义节点渲染,例如线框。谢谢,这真的很有帮助
     [Myview setDelegate:self];
     [[Myscene physicsWorld] setContactDelegate:self];
    
    -(void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact{}
    
    -(void)physicsWorld:(SCNPhysicsWorld *)world didEndContact:(SCNPhysicsContact *)contact{}
    
    -(void)physicsWorld:(SCNPhysicsWorld *)world didUpdateContact:(SCNPhysicsContact *)contact{}
    
    -(void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time{}
    -(void)renderer:(id<SCNSceneRenderer>)aRenderer didApplyAnimationsAtTime:(NSTimeInterval)time{}
    -(void)renderer:(id<SCNSceneRenderer>)aRenderer didRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time{}
    -(void)renderer:(id<SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time{}
    -(void)renderer:(id<SCNSceneRenderer>)aRenderer willRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time{}