ryno
ryno

Reputation: 966

SceneKit / ARKit updating a node every frame

I'm working with ARKit / SceneKit and I'm trying to have an arrow point to an arbitrary position I set in the world, but I'm having a bit of trouble. In my sceneView I have a scene set up to load in my arrow.

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the view's delegate
        sceneView.delegate = self
        guard let arrowScene = SCNScene(named: "art.scnassets/arrowScene.scn") else {
            fatalError("Scene arrow.scn not found")
        }
        
        let worldAnchor = ARAnchor(name: "World Anchor", transform: simd_float4x4(1))
        sceneView.session.add(anchor: worldAnchor)
        
        sceneView.scene = (arrowScene)
    }

I wish to then use SCNNode.look(at:) to point my arrow at the specified anchor, however, I am unsure how to get this to occur every frame. I know that I have access to special delegates provided by ARSCNView such as renderer(willUpdate node:), but I am unsure how to use these when the anchor is not changing positions whereas the arrow is.

Thanks for the help!

Upvotes: 0

Views: 613

Answers (1)

ZAY
ZAY

Reputation: 5015

You could do so by using the updateAtTime delegate function, but I strongly recommend you to use a SCNConstraint.

let lookAtConstraint = SCNLookAtConstraint(target: myLookAtNode)
lookAtConstraint.isGimbalLockEnabled = true // useful for cameras, probably also for your arrow.

// in addition you can use a position constraint
let positionConstraint = SCNReplicatorConstraint(target: myLookAtNode)
positionConstraint.positionOffset           = yourOffsetSCNVector3
positionConstraint.replicatesOrientation    = false
positionConstraint.replicatesScale          = false
positionConstraint.replicatesPosition       = true
    
// then add the constraints to your arrow node
arrowNode.constraints = [lookAtConstraint, positionConstraint ]

This will automatically adjust your node for each rendered frame.

Upvotes: 1

Related Questions