Introduction
I'm designing an iPhone game in Augmented Reality using ARKit. One of the parts of my game involves the user swiping to throw a ball at a target. My intent is to create a vector with the y value and z value of the target but the x value of where the user swipes. When testing this system, however, the ball always moves towards the left. I believe that it is an issue with the axes I'm using but I am unable to understand how to change this. The target can be anywhere on a plane in the AR world.
A depiction is provided in the image. The user swipes from the ball and the ball should move towards the y and z coordinates of the target and the x value of wherever the swipe ends.
Current Code
Most of the code I have used is based on the following Tutorial on RayWenderlich.com.
I start by implementing the touchesBegan and touchesEnded functions as follow to calculate the end point of the swipe and how quick the swipe was:
var startTouch: UITouch?
var endTouch: UITouch?
var startTouchTime: TimeInterval!
var endTouchTime: TimeInterval!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if self.currentMode == .throwingProjectiles {
guard let firstTouch = touches.first else { return }
let point = firstTouch.location(in: sceneView)
let hitResults = sceneView.hitTest(point, options: [:])
if hitResults.first?.node == projectileIndicator {
startTouch = touches.first
startTouchTime = Date().timeIntervalSince1970
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard startTouch != nil else { return }
endTouch = touches.first
endTouchTime = Date().timeIntervalSince1970
throwBall()
}
I then implement the throwBall() function as follows:
func throwBall() {
guard let endingTouch = endTouch else { return }
let firstTouchResult = sceneView.hitTest(
endingTouch.location(in: sceneView),
options: nil
).filter({
$0.node == targetNode || $0.node == floorNode
}).first
guard let touchResult = firstTouchResult else {return}
let vp = endingTouch.location(in: sceneView)
let vpWithDepth = SCNVector3Make(Float(vp.x), Float(vp.y), 0)
let scenePoint = sceneView.unprojectPoint(vpWithDepth)
let timeDifference = ( endTouchTime - startTouchTime)/4
let velocityComponent = Float(min(max(1 - timeDifference, 0.1), 10.0))
let impulseVector = SCNVector3(
x: scenePoint.x,
y: targetNode.worldPosition.y + 1.005 * velocityComponent * 5,
z: targetNode.worldPosition.z * velocityComponent * 10
)
spawnProjectile()
currentBallNode?.name = "Ball"
balls.append(currentBallNode!)
currentBallNode?.physicsBody?.applyForce(impulseVector, asImpulse: true)
currentBallNode = nil
startTouchTime = nil
endTouchTime = nil
startTouch = nil
endTouch = nil
}
The unproject point code is from here: https://stackoverflow.com/a/25154025/6642130
So my question is, how do I facilitate this throw?