SceneKit物理模拟的更新方法

6

我曾经使用过Sprite Kit并使用update方法来设置每个时间步骤需要处理的内容。但是现在我想学习SceneKit和Swift,并且似乎找不到相应的方法。

你能否为我提供一个实现SceneKit update方法的例子?谢谢。

1个回答

16

(是的,我知道这个问题是关于 SceneKit 而不是 SpriteKit,但它涉及到两个框架之间的共性和差异,所以在这个答案中我会涉及这些内容。)

在 SpriteKit 中,游戏循环方法(updatedidSimulatePhysics 等)最初是属于场景类 SKScene 的一部分。不过这并不总是最好的选择,你可能更想把场景实例当作数据而非实现游戏逻辑的地方(尤其是现在可以在 Xcode 6 的图形场景编辑器中完全构建场景了)。因此,在 iOS 8 和 OS X Yosemite 中,这些方法被放在了两个地方。如果你已经为每帧的游戏逻辑创建了 SKScene 子类,那么你可以继续使用它们。但是,如果你希望把代码放在其他地方,你可以在场景上设置一个代理,并在代理中实现对应的 SKSceneDelegate 方法。

SceneKit 更注重职责分离。一个 SCNScene 更接近于一个纯数据模型对象,而所有渲染循环功能都由用于显示场景的视图(或其他对象)管理。通常你会在一个 SCNView 中显示一个场景 —— 但也有其他类可以渲染场景,所以它们的公共 API 可在 SCNSceneRenderer 协议中找到。使用该协议定义的 delegate 属性来为你的视图设置代理,在代理中实现 SCNSceneRendererDelegate 方法,参与渲染循环的关键阶段。

SceneKit 的循环阶段几乎直接对应 SpriteKit 的循环阶段:update: 变成了 renderer:updateAtTime:didEvaluateActions: 变成了 renderer:didApplyAnimationsAtTime:(因为它包括 Core Animation 风格的动画和 SpriteKit 风格的操作),等等。


因此,要在 SceneKit 中实现与 SpriteKit 中每帧的 update 方法相当的功能,请按照以下步骤操作:

  1. 将你的自定义对象(比如一个视图控制器)设置为你的 SCNView 实例的 delegate

  2. 在这个自定义类中,实现下面的方法:

    func renderer(_ aRenderer: SCNSceneRenderer!, updateAtTime time: NSTimeInterval) {
        // per-frame code here
    }
    

或者对于其他SCNSceneRendererDelegate方法执行类似的操作,以便在处理操作或物理效果后执行每帧逻辑。


我试过这个......但还不完全正确。你认为问题出在哪里?我很困惑。覆盖func渲染器(_ aRenderer: SCNSceneRenderer!, 在时间上更新time:NSTimeInterval) { println(“你好\n”) } - Cherr Skees
2
这不是任何特定子类上的覆盖方法 - 请参见编辑后的答案。 - rickster
我想知道为什么他们在这里使用系统时间?如果时钟改变了,那不会导致出错吗? - Craig McMahon
嗨,我知道这是一篇旧帖子,但我想知道您是否能够提供更详细的示例来遵循您列出的步骤,特别是第一步,或者至少指向一个关于以这种方式编程的SceneKit的良好详细资源。非常感谢您发布如此完整的答案(至少对于比我更了解Swift的人来说)。 - Samuel Rabinowitz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接