I have a simple SCNNode in ARKit and I am trying to drag it wherever I moved my finger on the phone. Here is my code.
@objc func pan(recognizer :UIGestureR
Had the same issue. Using a SCNTransaction
did the trick for me.
@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
[...]
SCNTransaction.begin()
SCNTransaction.animationDuration = 0
imagePlane.position.x = hitTestResult.localCoordinates.x
imagePlane.position.y = hitTestResult.localCoordinates.y
SCNTransaction.commit()
}
I had a similar problem. Whilst you should use John's advice in the comments and use the pan gesture states correct (Began, Changed, Ended), I think the issue might be that you are grabbing the hitResult.node when you should be grabbing the parent of the node, or even the parent's parent, etc... I've had this issue and ended up fixing it by going up parent levels until the entire object was being selected instead of a part of it.
I handle translation with PanGesture like this. The division by 700 is to smooth and adjust speed of movement, I reached to that value by trial or error, you may want to experiment with it
@objc func onTranslate(_ sender: UIPanGestureRecognizer) {
let position = sender.location(in: scnView)
let state = sender.state
if (state == .failed || state == .cancelled) {
return
}
if (state == .began) {
// Check it's on a virtual object
if let objectNode = virtualObject(at: position) {
// virtualObject(at searches for root node if it's a subnode
targetNode = objectNode
latestTranslatePos = position
}
}
else if let _ = targetNode {
// Translate virtual object
let deltaX = Float(position.x - latestTranslatePos!.x)/700
let deltaY = Float(position.y - latestTranslatePos!.y)/700
targetNode!.localTranslate(by: SCNVector3Make(deltaX, 0.0, deltaY))
latestTranslatePos = position
if (state == .ended) {
targetNode = nil
}
}
}