Dragging SCNNode in ARKit Using SceneKit

元气小坏坏 提交于 2019-11-28 06:04:10

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
        }
    }
}

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.

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()
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!