首页 文章

SceneKit 物理在局部空间中添加速度

提问于
浏览
2

我试图通过向不同方向的轴添加或减去速度来使用 physicsBody.velocity 来操纵玩家节点。问题是我无法找到将其应用于局部空间的方法,或者至少应用与物体所面向方向相关的速度。换句话说,如果我没有旋转对象的节点,它可以正常工作。如果我这样做,仍然会将速度添加到未旋转的空间。我知道有一种方法可以将速度添加到当前的 SCNVector3,但我无法弄明白。

if isZThrustPositive {
        if let velocity = self.physicsBody?.velocity {
            if velocity.z * 100 <= 8000 {
                thrustDirection = SCNVector3(
                    x: velocity.x,
                    y: velocity.y,
                    z: velocity.z + kPlayerShipMainThrust)
                self.physicsBody?.velocity = thrustDirection
            }
        }
    }

我也试图以类似的方式使用 angularVelocity 旋转节点。只要节点没有移动或旋转,这样就可以正常工作。如果有,它似乎也在使用世界空间。

if isYRotatingPositive {
        if let angularVel = self.physicsBody?.angularVelocity {
            self.physicsBody?.angularVelocity = SCNVector4(
                x: angularVel.x,
                y: angularVel.y + kPlayerShipRotationSpeed,
                z: angularVel.z,
                w: angularVel.w + kPlayerShipRotationMagnitude)
        }
    }

物理模拟后,我正在更新节点的位置和旋转。我也尝试了convertPosition,但无法想出办法使这项工作。 (我得到了一些非常疯狂的结果)。任何帮助深表感谢。

更新我获得了 playerShip 对象,以便在旋转时在正确的方向上添加速度,但是如果没有朝正确的方向转动,我仍然无法执行多次旋转。对于船速,我做了这个:

if isXThrustPositive {
        thrustDirection = self.convertPosition(SCNVector3(x: kPlayerShipMainThrust, y: 0.0, z: 0.0), toNode: self.parentNode!)
        thrustDirection.x = thrustDirection.x - self.position.x
        thrustDirection.y = thrustDirection.y - self.position.y
        thrustDirection.z = thrustDirection.z - self.position.z
        self.physicsBody?.applyForce(thrustDirection, impulse: true)
    }

当尝试使用类似的旋转方法时(我知道它会注定失败),结果SCNVector3只是一个位置,而不是节点当前面向的方向。是否有关于convertTransform的信息以及我如何使用它?

1 回答

  • 1

    事实证明,我必须从场景的rootNode获得正确的位置,以根据SCNNode的当前方向执行正确的旋转。

    xAxis = self.convertPosition(SCNVector3Make(1.0, 0.0, 0.0), toNode: self.parentNode!)
    yAxis = self.convertPosition(SCNVector3Make(0.0, 1.0, 0.0), toNode: self.parentNode!)
    zAxis = self.convertPosition(SCNVector3Make(0.0, 0.0, 1.0), toNode: self.parentNode!)
    if isXRotatingPositive {
        self.physicsBody?.applyTorque(
            SCNVector4(
                x: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.x - self.position.x),
                y: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.y - self.position.y),
                z: sin(kPlayerShipRotationSpeed/2.0) * (xAxis.z - self.position.z),
                w: cos(kPlayerShipRotationSpeed/2.0) * kPlayerShipRotationMagnitude),
            impulse: true)
        }
    

    然后我只使用标准的四元数旋转公式来根据当前位置的新轴获得旋转。我希望这可以帮助其他人(并且有关 SceneKit 的更多信息即将发布)如果有任何 SceneKit 专家想对此发表评论或提供建议,我们非常感谢。 :)

相关问题