0
\$\begingroup\$

I am working on a game like soccer star and I made a controller using YouTube and stuff. I added two players in the same scene and put this script on them. But when I play with player 1, then player 2 does the same as they are controlled by the same touch. How can I make them work simultaneously?

The Upper half belongs to player 1 and the lower half belongs to player 2 and they are touching the same screen.

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

public class Ball : MonoBehaviour
{   
    public float Power = 10f;
    public float maxDrag = 5f;
    Rigidbody2D rb;
    LineRenderer lr;

    Vector3 dragStartPos;
    Touch touch2;    

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        lr = GetComponent<LineRenderer>();
    }

    // Update is called once per frame
    void Update()
    {    
        if (Input.touchCount > 0)
        {
            touch2 = Input.GetTouch(0);
    
            if (touch2.phase == TouchPhase.Began)
            {
                dragStart();
            }
            if (touch2.phase == TouchPhase.Moved)
            {
                dragging();
            }
            if (touch2.phase == TouchPhase.Ended)
            {
                dragRelease();
            }
        }            
    }    

    void dragStart()
    {
        dragStartPos = Camera.main.ScreenToWorldPoint(touch2.position);
        dragStartPos.z = 0f;

        lr.positionCount = 1;
        lr.SetPosition(0, transform.position);
    }


    void dragging()
    {
        Vector3 draggingPos = Camera.main.ScreenToWorldPoint(touch2.position);
        draggingPos.z = 0f;
        lr.positionCount = 2;
        lr.SetPosition(0, draggingPos);
    }    

    void dragRelease()
    {
        lr.positionCount = 0;
        Vector3 dragReleasePos = Camera.main.ScreenToWorldPoint(touch2.position);
        dragReleasePos.z = 0f;
        Vector3 force = dragStartPos - dragReleasePos;
        Vector3 clampedForce = Vector3.ClampMagnitude(force, maxDrag) * Power;
        rb.AddForce(clampedForce, ForceMode2D.Impulse);    
    }    
}
\$\endgroup\$
0
0
\$\begingroup\$

The fix is reasonably straightforward. Instead of responding to absolutely any touch on the screen, you need to introduce a variable to track which touch is "my currently active touch".

You can then be choosy about which touches meet the criteria to be claimed this way, and then respond only to movement / release of your claimed touch - the one that matches the variable.

// Set this to true for your top-half player, and false for the bottom-half player.
public bool topHalfIsMine;

public float Power = 10f;
public float maxDrag = 5f;

Rigidbody2D rb;
LineRenderer lr;
Vector2 dragStartPos;

int activeTouchId = -1;

void Start() {
    rb = GetComponent<Rigidbody2D>();
    lr = GetComponent<LineRenderer>();
}

void Update() {
    if (activeTouchId < 0) {
        TryStartTouch();
    } else {
        TrackTouch();
    }
}

void TryStartTouch() {
    for (int i = 0; i < Input.touchCount; i++) {
         var touch = Input.GetTouch(i);

         // Skip touches that are not new.
         if (touch.phase != TouchPhase.Began) continue;
         
         // Check which half of the screen the touch started on.
         bool onBottomHalf = touch.position.y < (Screen.height / 2);

         // Can I claim this touch as being in my half of the screen?
         bool mine = onBottomHalf ^ topHalfIsMine;

         // If not, skip it.
         if (!mine) continue;
         
         // Otherwise, this is my touch. Record its information.
         activeTouchId = touch.fingerId;
         dragStartPos = Camera.main.ScreenToWorldPoint(touch.position);

         // And configure the line.
         lr.positionCount = 1;
         lr.SetPosition(0, transform.position);

         break;
    }
}

void TrackTouch() {
    for (int i = 0; i < Input.touchCount; i++) {
        // Iterate through the touches till we find the one we claimed.
        var touch = Input.GetTouch(i);
        if (touch.fingerId != activeTouchId) continue;

        // Process the touch depending on its phase.
        switch (touch.phase) {
            case TouchPhase.Moved:

                // Update our line when it moves.
                Vector2 draggingPos = Camera.main.ScreenToWorldPoint(touch.position);

                lr.positionCount = 2;
                // Are you sure you don't want to be setting position 1 here?
                lr.SetPosition(0, draggingPos);

                break;

            case TouchPhase.Ended:
            case TouchPhase.Canceled:

                // Clear our active touch when it ends.
                activeTouchId = -1;

                lr.positionCount = 0;
                Vector2 dragReleasePos = Camera.main.ScreenToWorldPoint(touch.position);
       
                Vector2 force = dragStartPos - dragReleasePos;
                Vector2 clampedForce = Vector2.ClampMagnitude(force, maxDrag) * Power;
                rb.AddForce(clampedForce, ForceMode2D.Impulse);  

                break;
        }
        return;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Thank You So Much \$\endgroup\$
    – Nomi
    Jul 24 at 14:09

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.