0
\$\begingroup\$

I have been working for many hours trying to figure this out and i can't so I thought once again i'd trouble you kind folks.

Basically I am trying to keep this as simple as possible so I can get to grips with it, but eventually I am wanting to use it in a First Person Slingshot/Catapult style 3d game (knocking things over a bit like Angry Birds but first person 3d)

I've set up a dedicated class attached to my camera and it takes in the touchPos in screen coordinates and I have managed to figure out how to make a ray see which object its selecting, also have managed to convert the screen pos into either Viewport or World coordinates. But for some reason the World coordinates just keep coming throw as my camera coordinates no matter where I touch my screen (ie. My cameras transform position is 0,4,-1) and the touch was always 0,4

I changed to converting the actual touchPos and dividing by me screen width, height. And I've managed to get the things to move but they dont stick to my finger they move in a sort of wierd wave

I've been trying lots of things now, so the code is a little bit mixed up bute its not too lengthy and is only 2 classes so far so here it is (The summary of whats on screen right now is, an empty plane for ground, and one sphere unity object at position 0,4,0. The camera is also as stated above, there is nothing else except a light. All I want to learn at this stage really is how to 'grab' the ball and make it follow my finger EXACTLY along the X and Y axes):

public class TouchHandler : MonoBehaviour {
RaycastHit hit;
public LayerMask touchInputMask;

// Update is called once per frame
void Update () {
    if (Input.touchCount > 0)
    {
        foreach (Touch t in Input.touches)
        {
            Ray ray = gameObject.GetComponent<Camera>().ScreenPointToRay(t.position);


            if (Physics.Raycast(ray, out hit, touchInputMask))
            {
                GameObject objectThatsTouched = hit.transform.gameObject;

                if (t.phase == TouchPhase.Began)
                {
                    objectThatsTouched.SendMessage("OnTouchStart", t, SendMessageOptions.DontRequireReceiver);
                    //objectThatsTouched.SendMessage("OnTouchStart", hit, SendMessageOptions.DontRequireReceiver);

                }
                if (t.phase == TouchPhase.Moved)
                {
                    objectThatsTouched.SendMessage("OnTouchMoved", t, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Stationary)
                {
                    objectThatsTouched.SendMessage("OnTouchStill", t, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Ended)
                {

                    objectThatsTouched.SendMessage("OnTouchEnded", t, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Canceled)
                {

                    objectThatsTouched.SendMessage("OnTouchCancelled", t, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
}
} 

and:

public class Projectile : MonoBehaviour {
enum moveState { IDLE, PLAYER_AIM, MOVING }
moveState currentMoveState = moveState.IDLE;
Vector3 startPosition;
Rigidbody rb;
Camera cam;

Vector2 leftFingerPos = new Vector2();
Vector2 leftFingerLastPos = new Vector2();
Vector2 leftFingerMovedBy = new Vector2();

float slideMagnitudeX, slideMagnitudeY;


Vector2 myTouch = new Vector2();

// Use this for initialization
void Start () {
    startPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z);
    rb = GetComponent<Rigidbody>();
    cam = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
}

// Update is called once per frame
void Update () {

}

void OnTouchStart(Touch t)
{
    leftFingerPos = Vector2.zero;
    leftFingerLastPos = Vector2.zero;
    leftFingerMovedBy = Vector2.zero;

    slideMagnitudeX = 0;
    slideMagnitudeY = 0;

    // record start position
    leftFingerPos = t.position;
}

void OnTouchMoved(Touch t)
{
    leftFingerMovedBy = t.position - leftFingerPos; // or Touch.deltaPosition : Vector2
                                                    // The position delta since last change.
    leftFingerLastPos = leftFingerPos;
    leftFingerPos = t.position;

    // slide horz
    slideMagnitudeX = leftFingerMovedBy.x / Screen.width;


    // slide vert
    slideMagnitudeY = leftFingerMovedBy.y / Screen.height;

    myTouch = new Vector2((t.position.x / Screen.width), (t.position.y / Screen.height));

    // move this object
    transform.Translate(myTouch.x, myTouch.y, 0);
    Debug.Log("transform pos updated to = " + transform.position);

}

void OnTouchStationary(Touch t)
{
    //leftFingerLastPos = leftFingerPos;
    leftFingerPos = t.position;

    slideMagnitudeX = 0.0f;
    slideMagnitudeY = 0.0f;

}

void OnTouchEnded(Touch t)
{
    slideMagnitudeX = 0.0f;
    slideMagnitudeY = 0.0f;

    // TODO:  calculate force to apply based on currentPosition as opposed to startPos
}

void OnTouchCancelled(Touch t)
{
    slideMagnitudeX = 0.0f;
    slideMagnitudeY = 0.0f;
}
}

Thanks in advance for any suggestions

EDIT: I've also tried this (but RaycastHit hit.transform.position is always equal to the spheres position again and I dont know why):

public class TouchHandler : MonoBehaviour {
RaycastHit hit;
public LayerMask touchInputMask;

// Update is called once per frame
void Update () {
    if (Input.touchCount > 0)
    {
        foreach (Touch t in Input.touches)
        {
            Ray ray = gameObject.GetComponent<Camera>().ScreenPointToRay(t.position);


            if (Physics.Raycast(ray, out hit, touchInputMask))
            {
                GameObject objectThatsTouched = hit.transform.gameObject;

                if (t.phase == TouchPhase.Began)
                {
                    objectThatsTouched.SendMessage("OnTouchStart", hit, SendMessageOptions.DontRequireReceiver);
                    //objectThatsTouched.SendMessage("OnTouchStart", hit, SendMessageOptions.DontRequireReceiver);

                }
                if (t.phase == TouchPhase.Moved)
                {
                    objectThatsTouched.SendMessage("OnTouchMoved", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Stationary)
                {
                    objectThatsTouched.SendMessage("OnTouchStill", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Ended)
                {

                    objectThatsTouched.SendMessage("OnTouchEnded", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Canceled)
                {

                    objectThatsTouched.SendMessage("OnTouchCancelled", hit, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
}

}

\$\endgroup\$
  • \$\begingroup\$ You should try to explain what you want to do a bit more clearly before writing all the ways you've tried to fix the issue. This would help us fix the issue instead of fixing the not-working-solutions :) \$\endgroup\$ – Alexandre Vaillancourt Aug 22 '17 at 10:27
0
\$\begingroup\$

OK i actually found the solution. I had to use the hit.point variable. Then it was easy:

public class TouchHandler : MonoBehaviour {
RaycastHit hit;
public LayerMask touchInputMask;
GameObject objectThatsTouched;

// Update is called once per frame
void Update () {
    if (Input.touchCount > 0)
    {
        foreach (Touch t in Input.touches)
        {
            Ray ray = gameObject.GetComponent<Camera>().ScreenPointToRay(t.position);


            if (Physics.Raycast(ray, out hit))
            {
                objectThatsTouched = hit.transform.gameObject;
                Debug.Log("Hit Point = " + hit.point);
                if (t.phase == TouchPhase.Began)
                {
                    objectThatsTouched.SendMessage("OnTouchStart", hit, SendMessageOptions.DontRequireReceiver);
                    //objectThatsTouched.SendMessage("OnTouchStart", hit, SendMessageOptions.DontRequireReceiver);

                }
                if (t.phase == TouchPhase.Moved)
                {
                    objectThatsTouched.SendMessage("OnTouchMoved", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Stationary)
                {
                    objectThatsTouched.SendMessage("OnTouchStill", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Ended)
                {

                    objectThatsTouched.SendMessage("OnTouchEnded", hit, SendMessageOptions.DontRequireReceiver);
                }
                if (t.phase == TouchPhase.Canceled)
                {

                    objectThatsTouched.SendMessage("OnTouchCancelled", hit, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
}

}

and then i have classes like this to do the movement on the objects:

    void OnTouchStart(RaycastHit hit)
{
    transform.position = new Vector3(hit.point.x, hit.point.y, transform.position.z);
}

void OnTouchMoved(RaycastHit hit)
{
    transform.position = new Vector3(hit.point.x, hit.point.y, transform.position.z);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.