ios - 如何确保 SceneKit 相机始终指向特定位置
问题描述
我正在用 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) 的点在“查看”该点时旋转时都应保持静止。
任何指针都会非常感激,因为我无法弄清楚它为什么会这样。
解决方案
我假设您使用SCNView.allowsCameraControl = true
来移动相机。SceneKit 的这个内置设置实际上仅用于您的场景的调试目的。当您想对相机移动进行专门控制时,它不适合任何事情。
您应该尝试实现相机轨道,请参阅https://stackoverflow.com/a/25674762/3358138。
我可以用场景的“摇摆”中心重现您的问题,请参阅 Playground Gist https://gist.github.com/dirkolbrich/e2c247619b28a287c464abbc0595e23c。
相机轨道解决了这种“摆动”,让相机保持在中心,请参阅 Playground Gist https://gist.github.com/dirkolbrich/9e4dffb3026d0540d6edf6877f27d1e4。
推荐阅读
- reactjs - 作为道具传递给子组件的 SWR 数据创建无限获取循环
- html - 在进入 Jinja2 模板中动态创建的链接之前,如何使用确认模型?
- android - Android Emulator Location mocking with geo fix
- javascript - NiodeJS/如何在不下载的情况下找到外部托管图像的大小?
- julia - 朱莉娅 ReinforcementLearning.jl 中的神经网络架构
- python - 如何在 Pygame 中继续声音?
- android - android手动类型日期上的HTML日期选择器
- azure - 如何将 .app 文件从 Azure Pipeline 中的 .yml 文件部署到 Visual Studio App Center?
- .net - 尝试创建 Discord DM 时出现 SEHException
- javascript - 你好,我是初学者!我在如何停止我用 javascript 制作的倒计时有问题。你能帮我么