SceneKit检测SCNode何时不移动

时间:2019-04-28 16:38:11

标签: ios swift scenekit

在我的场景中,我扔了一个球。我想在球停止移动时将其移开。我的球有一个动态的物理物体,并且正在执行应有的碰撞等。

我想要做的是在球停止移动时将其从场景中淡出。当球的Z速度等于0时(在零时停止移动),我在球上调用一个函数。

func removeBowlingBallWhenNotMoving() {
        guard let bowlingBallNode = bowlingBallNode else {return}
        if let bowlingBallZVelocity = bowlingBallNode.physicsBody?.velocity.z {
            if Int(bowlingBallZVelocity) == 0 {
                performFadeOutOnBowlingBallWith(duration: 1.0)
            }
        }
    }

此方法在 didSimulatePhysicsAtTime 中被调用:(据我所知,它称为60fps)

func renderer(_ renderer: SCNSceneRenderer, didSimulatePhysicsAtTime time: TimeInterval) {
        bowlingBall.removeBowlingBallWhenNotMoving()
    }

我遇到的问题是,显然Z球的速度从零开始,并立即被移除。我只想在到达0时淡出而不是从0开始。我可以在日志中看到:

Alex 0
Alex 0
Alex 0
Alex 0
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -2
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex -1
Alex 0

我是在正确的委托函数中执行此操作吗?如果是,该如何忽略其起始速度?

2 个答案:

答案 0 :(得分:2)

创建节点时,您将通过node.position = SCNVector3Make(x,y,originZ)将其放置在现实世界中,这将成为起点。因此,如果您这样做:

if let bowlingBallZVelocity = bowlingBallNode.physicsBody?.velocity.z, bowlingBallNode.position.z != originZ {
            if Int(bowlingBallZVelocity) == 0 {
                performFadeOutOnBowlingBallWith(duration: 1.0)
            }
        }

这将防止您使其消失在第一个像素中。

您还可以通过比较当前的worldposition和节点worldposition

来防止这种情况的发生

答案 1 :(得分:1)

SceneKit公开了isResting属性:

  

SceneKit的物理模拟可能会自动将其设置为YES   身体不动,不受任何力的影响。