1
\$\begingroup\$

I'm using unity2D and C#, and I have a code for touch screen:

if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);

        if (touch.phase == TouchPhase.Began)
        {
            startTime = Time.time;
            startPos = touch.position;

        }
        else if (touch.phase == TouchPhase.Ended)
        {
            endTime = Time.time;
            endPos = touch.position;
            swipeDist = (endPos - startPos).magnitude;
            swipeTime = endTime - startTime;

            if (swipeTime < maxTime && swipeDist > minSwipeDist)
            {
                swipe();
            }

And this code for swipe:

void swipe()
{
     Vector2 distance = endPos - startPos;
    if (Mathf.Abs(distance.x) > Mathf.Abs(distance.y))
    { 
           if (distance.x > 0)
        {
            Debug.Log("Right swipe");
        }
        if (distance.x < 0)
        {
            Debug.Log("Left swipe");
        }
    }
    if (Mathf.Abs(distance.x) < Mathf.Abs(distance.y))
    {
        if (distance.y > 0)
        {
            Debug.Log("Up swipe");
        }
        if (distance.y < 0)
        {
            Debug.Log("Down swipe");
        }
    } 
}

}

How can I add to this code hold function, for for example move object at the screen?

\$\endgroup\$
  • \$\begingroup\$ You can't, not with this code. You need to write other code that will grab and move something. \$\endgroup\$ – jgallant Oct 4 '16 at 9:55
0
\$\begingroup\$

To add a simple drag functionality to your touch code you're going to need to know first what you're moving. This can be done by checking what is under the finger when the touch begins by whatever method you prefer and storing it just like your startTime and startPos.

Once you've got the object that you want to move stored you simply need to update the object's position on touch frames where it hasn't ended or canceled yet (you could probably rely on TouchPhase.Moved but I don't know if TouchPhase.Stationary is completely stationary, which is almost impossible in real use, or just close to it, which would cause a small amount of drift).

You can do this one of two ways: You can track of the difference between that frame and the previous frame's touch position and apply that difference to the touched gameobject's position; or, by also storing the offset of the touch to the object's position when you initially store the object, you can simply set the object's position each frame to that offset from whatever the touch position is.

Regardless of what method you use to move it, at this point all you have to do is make sure to clear the variable(s) you used on ended or canceled to make sure a drag only lasts one touch and you're set!

\$\endgroup\$
  • \$\begingroup\$ Thank you for the answer. In my game I have player (character), that go forward (in 2D platformer, forward = right). When I tap player is go for one step, but I want player go when I hold screen. I tried to use: TouchPhase.Stationary - this work, but character go even if I swipe - it's bad for me. Also I used timeSwipe == 0, but this work one time and not work at the second and third try. Help please. \$\endgroup\$ – Andrey Dubchak Oct 4 '16 at 22:34
  • \$\begingroup\$ Ah, didn't realize that's what you were going for. You have a few options there but if you want swiping to not move the player then you're going to need to wait to start moving the player until a swipe is no longer possible and make that determination as quickly as possible to add to responsiveness. If you do that, you simply wait to start moving until after Time.time - startTime > maxTime. You can hide this delay in a startup animation or you can make maxTime shorter if you're not detecting enough movement of the finger but that should take care of the basic "go" logic :) \$\endgroup\$ – Lunin Oct 5 '16 at 17:47
0
\$\begingroup\$

You can try this,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectObject : MonoBehaviour {

    // Use this for initialization
    GameObject hitObj;
    RaycastHit hit;
    private float speed = 1;

    void Start () {

    }

    // Update is called once per frame
    void Update () {
        foreach (Touch touch in Input.touches) {
            switch (touch.phase) {
                case TouchPhase.Began:
                    Ray ray = Camera.main.ScreenPointToRay (touch.position);
                    if (Physics.Raycast (ray, out hit, 10)) {
                            hitObj = hit.collider.gameObject;
                    }
                    break;
            case TouchPhase.Moved:

                // If the finger is on the screen, move the object smoothly to the touch position          
                float step = speed * Time.deltaTime; // calculate distance to move
                if(hitObj != null)
                    hitObj.transform.position = Camera.main.ScreenToWorldPoint(new Vector3 (touch.position.x, touch.position.y, hitObj.transform.position.z));
                break;
            }
        }
    }
}
\$\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.