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

标签 ios swift camera scenekit

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

SCNCamera 附加到 SNCNode 并位于游戏区域的边界之外,注视 (0,0,0)。

cameraNode.look(位于: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),其他点在每个角一个立方体)...

        addSphere(
            x: 0.0,
            y: 0.0,
            z: 0.0,
            radius: radius,
            textureName: "earth")

        addSphere(
            x: -2.0 * spacing,
            y: -2.0 * spacing,
            z: 0.0,
            radius: radius,
            textureName: "earth")
        addSphere(
            x: 2.0 * spacing,
            y: 2.0 * spacing,
            z: 0.0,
            radius: radius,
            textureName: "earth")


        addSphere(
            x: -2.0 * spacing,
            y: 2.0 * spacing,
            z: 0.0,
            radius: radius,
            textureName: "granite")
        addSphere(
            x: 2.0 * spacing,
            y: -2.0 * spacing,
            z: 0.0,
            radius: radius,
            textureName: "granite")


        addSphere(
            x: 0.0,
            y: -2.0 * spacing,
            z: -2.0 * spacing,
            radius: radius,
            textureName: "slime")
        addSphere(
            x: 0.0,
            y: 2.0 * spacing,
            z: 2.0 * spacing,
            radius: radius,
            textureName: "slime")


        addSphere(
            x: 0.0,
            y: 2.0 * spacing,
            z: -2.0 * spacing,
            radius: radius,
            textureName: "wood")
        addSphere(
            x: 0.0,
            y: -2.0 * spacing,
            z: 2.0 * spacing,
            radius: radius,
            textureName: "wood")

此代码的行为是,所有内容都围绕 (0,0,0) 对称,位于 (0,0,0) 的节点恰好位于应有的位置。

如果我将这个节点引入场景中,一切都会出错......

        addSphere(
            x: 6.0,
            y: 6.0,
            z: 6.0,
            radius: radius,
            textureName: "earth")

我试过为每个质量为零的节点添加一个固定的物理体,但没有成功。就好像相机不再直视 (0,0,0),而是受到场景中节点的影响。

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

这是 addSphere 方法 ...

    internal func addSphere(x: Float, y: Float, z: Float, radius: Float, color: UIColor, textureName: String) -> SCNNode {

        let sphereGeometry = SCNSphere(radius: CGFloat(radius))
        sphereGeometry.firstMaterial?.diffuse.contents = UIImage(imageLiteralResourceName: textureName)

        let sphereNode = SCNNode(geometry: sphereGeometry)
        sphereNode.name = "dot"

        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)

        return sphereNode
    }

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

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

最佳答案

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

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

我可以用场景的“摆动”中心重现您的问题,请参阅 Playground 要点 https://gist.github.com/dirkolbrich/e2c247619b28a287c464abbc0595e23c .

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

关于ios - 如何确保 SceneKit 相机始终指向特定位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56449492/

相关文章:

objective-c - 如何在 UITextfield 中输入时和输入后放置货币符号?

ios - NSTimer - 整数乘法

ios - 如何在 swift5 和 Alamofire 5 beta 版本中获取和保存响应?

objective-c - Swift:对具有相同选择器的对象进行类型转换

arrays - 是否可以在 swift 2.2 中为整数数组构建通用转换?

.net-core - 带有Blazor的访问设备摄像头

ios - 快门动画 AVFoundation iphone

ios - 如何从IOS中的多个数组中搜索UITableView中的单元格

java - 处理——定义相机

ios - 在单个 UIWebView 中打开 URL