I'm learning scenekit and messing around with the framework. I have everything set up to where their is a scnnode named "jumpBall," has dynamic physics, and rests on a floor object. Currently, the "jumpBall" can be dragged horizontally based on a pan gesture. The "jumpBall" can be dragged from around worldPosition "x = -3.5" to "x = 3.5." Once the ball hits this barrier, it kicks out of the pan gesture function unless it is being dragged the opposite way of barrier. However, these barriers do not always work, and fast pan gestures can sometimes see the ball clipping through these barriers. I don't want the ball being clipped outside of these drag barriers.
@objc func handlePan(panGesture: UIPanGestureRecognizer) {
guard let jumpBall = self.jumpBall else { return }
guard let view = view as? SCNView else { return }
let location = panGesture.location(in: self.view)
let ballPositionX = jumpBall.worldPosition.x
switch panGesture.state {
case .began:
guard let hitNodeResult = view.hitTest(location, options: nil).first else { return }
panStartZ = CGFloat(view.projectPoint(lastPanLocation).z)
lastPanLocation = hitNodeResult.worldCoordinates
case .changed:
//the '380' value represents the y value CGPoint of the floor
let worldTouchPosition = view.unprojectPoint(SCNVector3(location.x, 380, panStartZ!))
//this represents the direction of the ball
//a positive dragX means the ball is moving right
//a negative dragX means the ball is moving left
let dragX = (worldTouchPosition.x - lastPanLocation.x) * 1.1
let movementVector = SCNVector3(dragX, worldTouchPosition.y - lastPanLocation.y, 0)
//break out if the ball is around the right wall and moving right
if(ballPositionX > 3.2 && ballPositionX < 3.6) {
if(dragX > 0) {
break
}
}
//break out if the ball is around the left wall and moving left
if(ballPositionX < -3.2 && ballPositionX > -3.6) {
if(dragX < 0) {
break
}
}
jumpBall.localTranslate(by: movementVector)
self.lastPanLocation = worldTouchPosition
case .ended:
//brute force the ball back inside the barriers
if(jumpBall.worldPosition.x > 3.5) {
jumpBall.worldPosition.x = 3.5
} else if(jumpBall.worldPosition.x < -3.5) {
jumpBall.worldPosition.x = -3.5
}
default:
break
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…