0
votes

I have been 3 days trying to solve this problem but still nothing. I am working on a game where by using the touch screen of the phone, a ball would move to the X position of your finger when you touch the screen, and do something different when while holding your first finger, you tap with the second finger.

The phone does detect whether it is the first touch or the second touch, and the second does what it is supposed to do. But the first touch does not do what it is supposed to. I know it is detected, because I already tested it. But there must be some mistake with the way I am making the ball move.

This is my code.

I have tried using AddForce, but I don't want the ball to keep going after I release my finger. Also tried many types of touches, also tried using a Joystick, but after I release my finger, the ball keeps going (a little bit further).

 foreach (Touch touch in Input.touches)
{

    if (touch.fingerId == 0)
    {    

            Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
            touchPosition.z = 0f;
            if (touchPosition.x > transform.position.x)
            {
                transform.position = new Vector3(transform.position.x + 10, transform.position.y, transform.position.z);
            }
            else if (touchPosition.x < transform.position.x)
            {
                transform.position = new Vector3(transform.position.x - 10, transform.position.y, transform.position.z);
            }

    }


    if (touch.fingerId == 1)
    {

        Accelerate();
    }
}

I would like the code to detect whether my finger is more to the left or more to the right of the ball, and move the player to the left or right accordingly. I am also trying to make it move "smoothly", not too fast, not too slow. And afterwards, if I move my finger without lifting the finger up, the ball would still follow it.

I have spent 3 days trying different ideas....I appreciate any help. Also already searched in many posts, and unity's documentation and forum. Also searched for youtube videos...but have not found nothing really useful.

edit. forgot to mention. This is exclusively for android at the moment.

2

2 Answers

0
votes

I solved it like this. Not sure if it is the best way, but it works.

 if (!accelerated)
    {

        Vector3 playerPosition = gameObject.transform.position;



        foreach (Touch touch in Input.touches)
        {


            if (touch.fingerId == 0)
            {


                playerPosition = Camera.main.WorldToScreenPoint(playerPosition);
                Vector2 touchPosition = touch.position;
                if (touchPosition.x -15 >= playerPosition.x)
                {
                    transform.Translate(Vector3.right * Time.deltaTime * speed);

                }
                else if (touchPosition.x + 15 <= playerPosition.x)
                {
                    transform.Translate(-Vector3.right * Time.deltaTime * speed);
                }


            }


            if (touch.fingerId == 1)
            {

                Accelerate();
            }
        }




    }
0
votes

I notice in your second else if statement you check your position against a ball object. Is this script not attached to the ball you are trying to move? This script is currently changing the transform.position of whatever GameObject it is attached to.

I'm going to do some assuming about that information, instead of:

transform.position = new Vector3(transform.position.x + 10, transform.position.y, transform.position.z);

Try:

ball.transform.position = new Vector3(ball.transform.position.x + 10, ball.transform.position.y, ball.transform.position.z);

As an additional sidenote, calling transform.position on an object can be an expensive call if it's made frequently. You're making 3 transform.position reads and a write in one line here. I would recommend caching your transform.position to a Vector3 and updating that variable's values in your logic, then re-assigning it to the transform at the end. Like this:

Vector3 ballPosition = ball.transform.position;
ballPosition.x = ballPosition.x + 10;
ball.transform.position = ballPosition;

Update

It looks like you're using Touch.fingerId, which explicitly states:

Touch.fingerId is not the same as "first" touch, "second" touch and so on. It is merely a unique id per gesture. You cannot make any assumptions about fingerId and the number of fingers actually on screen, since virtual touches will be introduced to handle the fact that the touch structure is constant for an entire frame (while in reality the number of touches obviously might not be true, e.g. if multiple tappings occur within a single frame).

Touch.fingerId doesn't actually tell you which finger it was. It's merely a reference. This is because the touches are read on every frame, and the order of the touches can differ between frames. I would recommend the following:

void Update()
{
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);
        //Move ball code here
    }
}