0
votes

I am aiming to move the inhabitants in a scene randomly around inside a bounded area. Every 3 seconds the x, y, and z positions of the SCNVector3 are changed then the node moves to those points.

The problem im having is the nodes are not moving to those points. The points change as seen in the print("running: x\(self.x) y\(self.y) z\(self.z) on - \(node.name!)") line. I assume the SCNAction.move(to:) action is being called but for some reason that line does nothing.

No errors are being thrown the nodes just spawn at the random point and never move.

This is the code I have to achive the current movements:

    var x = Float.random(in: -0.25...0.265)
    var y:Float = 0
    var z = Float.random(in: -0.3...0.215)

    func spawnInhabitants() {
        let type = skyBalls[_index].getInhabitantType().rawValue
        let scene = SCNScene(named: "art.scnassets/inhabitants/\(type).scn")!
        let inhabitantNode:SCNNode = scene.rootNode.childNode(withName: type, recursively: false)!
        inhabitantNode.scale = SCNVector3(0.000075, 0.000075, 0.000075)
        inhabitantNode.physicsBody?.physicsShape = SCNPhysicsShape(node: inhabitantNode)
        inhabitantNode.physicsBody?.type = .dynamic
        inhabitantNode.physicsBody?.isAffectedByGravity = false
        inhabitantNode.physicsBody?.categoryBitMask = 1
        inhabitantNode.physicsBody?.collisionBitMask = 6
        inhabitantNode.physicsBody?.contactTestBitMask = 1
        for inhab in skyBalls[_index].getInhabitants() {
            x = Float.random(in: -0.25...0.265)
            y = 0
            z = Float.random(in: -0.3...0.215)
            inhabitantNode.position = SCNVector3(x, y, z)
            let move_around = SCNAction.run { node in
                self.x = Float.random(in: -0.25...0.265)
                self.y = 0
                self.z = Float.random(in: -0.3...0.215)
                print("running: x\(self.x) y\(self.y) z\(self.z) on - \(node.name!)")
            }
            let move = SCNAction.move(to: SCNVector3(x, y, z), duration: 3) //<- This is the problem 
            let seq = SCNAction.sequence([move_around, move])
            let i = skyBalls[_index].getInhabitants().firstIndex(of: inhab)
            inhabitantNode.name = "\(type)\(i!)"
            inhabitantNode.runAction(SCNAction.repeatForever(seq))
            colonyScene.rootNode.addChildNode(inhabitantNode.copy() as! SCNNode)
        }
    }

As a note:

skyBalls[_index].getInhabitantType().rawValue 

^Returns a String of the enum type for the inhabitant (mostly used for naming)

skyBalls[_index].getInhabitants()

^returns the list of inhabitants form the instance of skyBalls and an index. more specifically an array of inhabitants.

colonyScene

^This is the SCNScene for the view.

Thanks in advance.

1

1 Answers

0
votes

Your move action might be using x, y, z values at the time the action is created. So you instead might try to create a new action inside of the run action after generating random values... (I simplified your code snippet to test this approach)

    for inhab in skyBalls {
        inhab.position = SCNVector3(x, y, z)
        let move_around = SCNAction.run { node in
            self.x = Float.random(in: -0.25...0.265)
            self.y = 0
            self.z = Float.random(in: -0.3...0.215)
            print("running: x\(self.x) y\(self.y) z\(self.z) on - \(node.name)")
            let moveAction = SCNAction.move(to: SCNVector3(self.x, self.y, self.z), duration: 3)
            node.runAction(moveAction)
        }
        let wait = SCNAction.wait(duration: 3) // make same as moveAction duration
        //let move = SCNAction.move(to: SCNVector3(x, y, z), duration: 3) //<- This is the problem
        let seq = SCNAction.sequence([move_around, wait])
        inhab.runAction(SCNAction.repeatForever(seq))
        scnView.scene!.rootNode.addChildNode(inhab)
    }

Hope this helps