如何确保 SceneKit 相机始终指向特定位置

Posted

技术标签:

【中文标题】如何确保 SceneKit 相机始终指向特定位置【英文标题】:How to ensure SceneKit camera always points at specific position 【发布时间】:2019-10-20 07:33:37 【问题描述】:

我正在用 Swift 5 编写游戏(但我最近通过游戏更新了 Swift 4 也有同样的问题),我所有的 SCNNode 都以 SCNVector3Zero 为中心。换句话说,(0,0,0) 位于我的游戏区域的中心。

SCNCamera 连接到一个 SNCNode 并位于游戏区域的边界之外,查看 (0,0,0)。

cameraNode.look(at: SCNVector3Zero)

如果我在场景中放置 5 个节点,都在 y=0 平面上,(0,0,0), (-1,0,-1), (1,0,1), (-1, 0,1) 和 (1,0,-1) 就像骰子的表面显示 5,一切都很好。我可以在 (0,0,0) 处的节点保持居中不动的情况下围绕场景旋转。

如果我添加第二行,那么第一行移动到 y=1,第二行获取 y=-1 的节点,场景在旋转时会稍微摇晃。

节点离中心越远,这种摆动就越夸张。

这是设置场景的代码(这个例子有三行,看起来像一个三维的“五”面骰子,点在 (0,0,0) 的中心,其他点在每个角一个立方体)...

添加球体( x: 0.0, y: 0.0, z: 0.0, 半径:半径, 纹理名称:“地球”) 添加球体( x:-2.0 * 间距, y:-2.0 * 间距, z: 0.0, 半径:半径, 纹理名称:“地球”) 添加球体( x:2.0 * 间距, y:2.0 * 间距, z: 0.0, 半径:半径, 纹理名称:“地球”) 添加球体( x:-2.0 * 间距, y:2.0 * 间距, z: 0.0, 半径:半径, 纹理名称:“花岗岩”) 添加球体( x:2.0 * 间距, y:-2.0 * 间距, z: 0.0, 半径:半径, 纹理名称:“花岗岩”) 添加球体( x: 0.0, y:-2.0 * 间距, z:-2.0 * 间距, 半径:半径, 纹理名称:“粘液”) 添加球体( x: 0.0, y:2.0 * 间距, z:2.0 * 间距, 半径:半径, 纹理名称:“粘液”) 添加球体( x: 0.0, y:2.0 * 间距, z:-2.0 * 间距, 半径:半径, 纹理名称:“木头”) 添加球体( x: 0.0, y:-2.0 * 间距, z:2.0 * 间距, 半径:半径, 纹理名称:“木头”)

这段代码的行为是,一切都围绕 (0,0,0) 对称,并且 (0,0,0) 处的节点准确地保持在应有的位置。

如果我把这个节点引入到场景中,那就大错特错了……

添加球体( x: 6.0, y: 6.0, z: 6.0, 半径:半径, 纹理名称:“地球”)

我尝试向每个质量为零的节点添加一个固定的物理体,但无济于事。这就像相机不再直视(0,0,0)而是受到影响,而是场景中的节点。

我尝试了各种添加节点的排列方式,在某些测试中,似乎添加任何对 z 轴有价值的东西都会导致问题

这是 addSphere 方法...

internal func addSphere(x: Float, y: Float, z: Float, radius: Float, color: UIColor, textureName: String) -> SCNNode 让sphereGeometry = SCNSphere(半径:CGFloat(半径)) sphereGeometry.firstMaterial?.diffuse.contents = UIImage(imageLiteralResourceName: textureName) 让sphereNode = SCNNode(几何:sphereGeometry) sphereNode.name = "点" sphereNode.position = SCNVector3(x: x, y: y, z: z) sphereNode.lines = []; sphereNode.ignoreTaps = false sphereNode.categoryBitMask = NodeBitMasks.dot //sphereNode.physicsBody = SCNPhysicsBody(type: .static, shape: nil) self.rootNode.addChildNode(sphereNode) 返回 sphereNode

没有错误,正如您所料,任何位于 (0,0,0) 的点在“查看”该点时旋转时都应保持静止。

任何指针都将不胜感激,因为我无法弄清楚它为什么会这样。

【问题讨论】:

您的相机设置是什么?您的相机放置在哪里? 抱歉,我不知道有人回复了。我没有被告知。相机沿 X 轴定位,在 y=0 上方约 30 度,指向 0,0,0 【参考方案1】:

我假设您使用SCNView.allowsCameraControl = true 来移动相机。 SceneKit 的这个内置设置实际上仅用于您的场景的调试目的。当您想对相机移动进行专门控制时,它不适合任何事情。

您应该尝试实现相机轨道,请参阅https://***.com/a/25674762/3358138。

我可以通过场景的“摇摆”中心重现您的问题,请参阅 Playground Gist https://gist.github.com/dirkolbrich/e2c247619b28a287c464abbc0595e23c。

相机轨道解决了这种“摆动”问题,让相机保持在中心位置,请参阅 Playground Gist https://gist.github.com/dirkolbrich/9e4dffb3026d0540d6edf6877f27d1e4。

【讨论】:

以上是关于如何确保 SceneKit 相机始终指向特定位置的主要内容,如果未能解决你的问题,请参考以下文章

在 Scenekit 中移动相机

SceneKit:在 Swift 4 中缩放相机

SceneKit:关于定位相机节点的数学问题

Scenekit - 将子节点(平面节点)添加到相机前面的父节点(球体节点)

如何在 SceneKit 中将 allowCameraControl 与相机节点一起使用

正交投影中的相机位置