How to apply offset to touch position when dragging object

Hi,

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

Im trying to re write it in java script what dose the “out” in the ray cast do i cant get it to work?

steve,ok im trying to do it in java script what is the “out” in the ray cast doing??

thanks
steve

Well i might be late,but i have some solution,i was making a game and i had that offset,i did like this

void Update() {

  if (Input.GetMouseButtonDown (0)) {
				mouseposition = Input.mousePosition;
				Vector3 MousePositionToWorld = Camera.main.ScreenToWorldPoint (mouseposition);
				offset = transform.position - MousePositionToWorld;
				offset.z = 0;
			}
			if (Input.GetMouseButton (0)) {
				mouseposition = Input.mousePosition;
				mouseposition.z = 1;

				transform.position = Camera.main.ScreenToWorldPoint (mouseposition) + offset;
			}
}

Just add raycast to the collider of object you want to drag and i think youre good to go