Alex McPherson
Alex McPherson

Reputation: 3195

SceneKit detect when SCNode is not moving

In my scene I throw in a ball. I want to remove my ball when it stops moving. My ball has a dynamic physics body and is performing collisions as it should etc.

What I want to do is fade out my ball from the scene when it has stopped moving. I call a function on my ball when its Z velocity equals 0 as in zero stopped moving.

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

This method is called in didSimulatePhysicsAtTime: (which is called 60fps as I understand it)

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

The issue I am having is that obviously the balls Z velocity starts at zero and is removed right away. I only want to fade it out when it reaches 0 not starts at 0. I can see in the log:

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

Am I performing this in the correct delegate function and if so how do ignore its starting velocity?

Upvotes: 1

Views: 156

Answers (2)

mnuages
mnuages

Reputation: 13462

SceneKit exposes the isResting property:

SceneKit’s physics simulation may automatically set it to YES if the body is not moving and not affected by any forces.

Upvotes: 1

Vollan
Vollan

Reputation: 1915

When you create the node you place it in the real world by node.position = SCNVector3Make(x,y,originZ) that will become the start point. so if you do it like this:

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

It will prevent you from making it disappear in the first pixel.

You can also prevent it from happening by comparing your current worldposition and the nodes worldposition

Upvotes: 2

Related Questions