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

时间:2019-06-04 18:32:53

标签: ios swift camera 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)就像骰子的表面显示五个一样,都很好用。我可以绕场景旋转,使(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轴值的东西,引起了问题

这是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)的任何点都应保持静态。

任何指针都将不胜感激,因为我无法弄清楚为什么它如此表现。

1 个答案:

答案 0 :(得分:1)

我假设您使用SCNView.allowsCameraControl = true来移动相机。 SceneKit的此内置设置实际上仅用于调试场景。如果您想对摄像机的运动进行专门控制,那么它就不适合任何事情。

您应该尝试实现摄像头轨道,请参见https://stackoverflow.com/a/25674762/3358138

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

摄影机轨道解决了这一“摆动”问题,让摄影机停留在中央,请参见“游乐场要旨https://gist.github.com/dirkolbrich/9e4dffb3026d0540d6edf6877f27d1e4”。