0

How can I use applyForce() to an SCNNode so that it goes in the direction of another SCNNode?

I do know the positions of both nodes.

I am aware that I can use SCNAction.move(to: position, duration: 3), but that doesn't meet my needs - as I don't want every node taking the same duration to get to the destination. I want all nodes to travel the same speed.

The goal is to have a bullet leave one node and go to towards another node. No need to update path (like a real bullet).

let bullet = SCNNode(geometry: SCNSphere(radius : 0.1))
bullet.position = enemy.position
bullet.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(node: bullet, options: nil))
bullet.physicsBody?.isAffectedByGravity = false

// player.position doesn't do what I thought it would... 
let vector = SCNVector3(player.position.x * 100, player.position.y * 100, player.position.z * 100)
bullet.physicsBody?.applyForce(vector, asImpulse: true)

bullet.runAction( SCNAction.sequence([
    SCNAction.wait(duration: 5),
    SCNAction.removeFromParentNode()]
))
self.sceneView.scene.rootNode.addChildNode(bullet)

While I'm determined to find this answer I have thought of a way to keep the speed of the bullet constant no matter the distance of the two nodes. I wanted to provide this here in case someone runs into a similar issue but I didn't want to provide this as the answer - as it's still using the move(to:) instead of applyForce().

let bullet = SCNNode(geometry: SCNSphere(radius: 0.1))
    bullet.geometry?.firstMaterial?.diffuse.contents = UIColor.green
    let enemy = timer.userInfo as! Enemy
    bullet.position = enemy.position
    bullet.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(node: bullet, options: nil))
    bullet.physicsBody?.isAffectedByGravity = false
    bullet.physicsBody?.categoryBitMask = BitMaskCategory.enemyBullet.rawValue
    bullet.physicsBody?.contactTestBitMask = BitMaskCategory.player.rawValue

    let lineX = playerNode.position.x - bullet.position.x
    let lineY = playerNode.position.y - bullet.position.y
    let lineZ = playerNode.position.z - bullet.position.z
    let distance = sqrtf(lineX*lineX + lineY*lineY + lineZ*lineZ)
    let fireBulletAction = SCNAction.move(to: playerNode.position, duration: (TimeInterval(distance / BASE_BULLET_SPEED)))
    bullet.runAction(SCNAction.group([
        fireBulletAction,
        SCNAction.sequence([
            SCNAction.wait(duration: 5),
            SCNAction.removeFromParentNode()]
        )]
    ))
    self.sceneView.scene.rootNode.addChildNode(bullet)
R Bradshaw
  • 173
  • 11
  • So you want the bullet to move specifically toward another node, or move in the direction that a specific node is facing? – drewster Apr 16 '18 at 01:26
  • Correct. But without using SCNAction.move - I'd prefer the applyForce(). Just using SCNAction.move (how I'm doing it now) I'm not able to get the behavior I want. – R Bradshaw Apr 16 '18 at 13:55

0 Answers0