I've been working on a script for dragging an object using touch position for iOS. I currently have a the object following along with a 1 finger touch as it moves across the screen. However, when the finger begins to move, the gameObject snaps it's center to the touch position. I know I need to apply an offset of the gameObject's transform.position from the touch position, but I'm not sure how to go about it. Can someone please help me to get on the right track. Here is a section of the script that handles the dragging. It's C#, which I'm not currently very good with.
Thanks!
// one finger drag gameObject movement
if (iPhoneInput.touchCount == 1) {
Ray ray = camera.ScreenPointToRay(Input.GetTouch(0).position);
RaycastHit hit;
iPhoneTouch f0 = iPhoneInput.GetTouch(0);
if (Physics.Raycast (ray, out hit, 100)) {
//Check to see if object hit is been set to moveable
if(hit.collider.tag == "Moveable"){
if(f0.phase == iPhoneTouchPhase.Moved || f0.phase == iPhoneTouchPhase.Began) {
Vector3 touchPos = Camera.main.ScreenToWorldPoint(new Vector3(f0.position.x, f0.position.y, Camera.main.farClipPlane));
//add the x and z position to new vector3
Vector3 newPos = transform.position;
newPos.x = touchPos.x;
newPos.z = touchPos.z;
transform.position = newPos;//Vector3 is a struct must be set from new Vector3
}
}
}
}
I was able to get everything working. Steven Fulfer (twitter @foofman) and John Lacoviello (twitter @mystaticself) sent me some code that solved the problem and I wanted to post their solutions here for others who find this question.
SOLUTION 1: Steven Fulfer
// one finger drag gameObject movement
if (Input.touchCount == 1) {
//Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
RaycastHit hit;
//check to see if item has been hit and set start and hit variables
if (Physics.Raycast (ray, out hit, 100)) {
//Check to see if object hit is been set to moveable
if(hit.collider.tag == "Moveable"){
if (!startTouch) {
hitDistance = hit.distance;
//mouse
//startTouchPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, hitDistance)); //Camera.main.farClipPlane
//touch
startTouchPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, hitDistance)); //Camera.main.farClipPlane
startTouch = true;
}
}
}
if (startTouch) {
//mouse
//Vector3 curntTouchPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, hitDistance));
//touch
Vector3 curntTouchPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, hitDistance));
Vector3 newPos = transform.position;
newPos.x = curntTouchPos.x;
newPos.z = curntTouchPos.z;
newPos.x = startItemPosition.x + (curntTouchPos.x - startTouchPos.x);
newPos.z = startItemPosition.z + (curntTouchPos.z - startTouchPos.z);
transform.position = newPos;//Vector3 is a struct must be set from new Vector3
}
} else {
//mouse button has been released
startTouch = false;
//needs to start where it left off
startItemPosition = transform.position;
}
SOLUTION 2: John Lacoviello
// one finger drag gameObject movement
if (iPhoneInput.touchCount == 1) {
Touch f0 = Input.GetTouch(0);
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100)) {
//Check to see if object hit is been set to moveable
if(hit.collider.tag == "Moveable"){
if (f0.phase == TouchPhase.Began) {
screenPos = Camera.main.WorldToScreenPoint(transform.position);
offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(f0.position.x, f0.position.y, screenPos.z));
}else if(f0.phase == TouchPhase.Moved){
currentScreenPos = new Vector3(f0.position.x, f0.position.y, screenPos.z);
currentPos = Camera.main.ScreenToWorldPoint(currentScreenPos) + offset;
transform.position = currentPos;
}
}
}
}
I don't have an easy way to test this, so you might have to tweak it slightly. I think the approach is correct, though I have trouble visualizing things like this without trying them, so I may have gotten the order wrong on the offset math. (edit to fix typo, sigh)
// we already know we are within the object bounds
// so calculate the offset between the object center and the touch point
Vector3 offsetPosition = transform.position - touchPos;
//add the x and z position to new vector3
Vector3 newPos = touchPos;
newPos.x += offsetPosition.x;
newPos.z += offsetPosition.z;
newPos.y = transform.position.y;
transform.position = newPos; //Vector3 is a struct must be set from new Vector3