找出SCNNode从SCNScene消失的时间

时间:2015-01-11 19:45:02

标签: objective-c scenekit

从场景中删除SCNNode时是否会调用特定方法?

- (无效)removeFromParentNode;

不会在SCNNode对象上调用。

设置场景

我正在使用重力来拉下一个物体。当一个物体走得太远时,它会自动消失,并且绘制调用和多边形计数会减少。所以SCNNode肯定会被破坏,但有没有办法可以解决这个问题呢?

2 个答案:

答案 0 :(得分:3)

其他答案已经很好地涵盖了这一点,但要进一步说明:

首先,您的节点不会从场景中移除 - 其内容通过相机的视锥体,这意味着SceneKit知道它不需要向GPU发出绘制调用渲染它。如果您enumerate the child nodes的场景(或任何父级包含您正在谈论的节点),您会发现他们仍然在那里。你失去了一些渲染性能成本,因为SceneKit不需要为它知道在框架中看不到的东西发出绘图调用。

(正如Tanguy的答案所述,这可能是因为你的zFar设置。或者可能不是 - 它取决于节点从相机中掉出的方向。)

但是如果你继续添加节点并让物理学将它们从屏幕上移除,那么你将累积预渲染性能成本,因为SceneKit必须每帧和每个人都走过场景图它需要向哪些节点发出绘制调用。每个节点的成本相当小,但最终可能会增加您不想处理的内容。

而且,既然你想在节点失控时发生一些事情,你只需要找到一个很好的机会来处理它并清理消失的节点。

那么该怎么做?嗯,你有几个选择。如前所述,您可以在渲染循环中放置一些内容来检查每个帧上每个节点的可见性:

- (void)renderer:(id<SCNSceneRenderer>)renderer didSimulatePhysicsAtTime:(NSTimeInterval)time {
    if (![renderer isNodeInsideFrustum:myNode withPointOfView:renderer.pointOfView]) {
        // it's gone, remove it from scene
    }
}

但这是一个在每一帧都运行的有点昂贵的检查(记住,你在这里以30或60 fps为目标)。更好的方法是让物理系统帮助你:

  1. 创建一个SCNBox几何体的节点,该节点足够大,可以捕获&#34;从屏幕上掉下来的一切。
  2. 为该节点提供一个静态物理体,并设置类别和碰撞位掩码,以便下降的节点与之发生碰撞。
  3. 将节点放在视锥体之外,以便落下的物体在它们离开视线后立即撞到它。
  4. 实施联系委托方法以销毁下降的节点:

    - (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact {
        if (/* sort out which node is which */) {
            [fallingNode removeFromParentNode];
            // ... and do whatever else you want to do when it falls offscreen.
        }
    }
    

答案 1 :(得分:1)

如果物体超过活动相机的ZFar属性,则物体将消失。 (默认值为100.0) 正如DavidRönnqvist在评论中所说,您的节点不会被销毁,您仍然可以修改其属性。

如果你想连接你的Node的几何消失,你可以计算你的活动相机和你的节点之间的距离,并在渲染循环的每一帧检查它,以便在它高于100时触发一个动作。

如果要在更远的距离渲染节点,只需修改相机的ZFar属性即可。