Preventing touch controls from appearing when touching other UI objects like buttons

Hi, I’m having some trouble with touch controls.
I have two thumb sticks (one left and one right) that appear on the screen depending on where the player touches. These then control the character movement depending on where the players fingers move.

The trouble I’m having is making the thumb sticks not appear when the player touches another UI element such as a button.

I’ve been having a tinker but all of my solutions so far tend to be attached to the buttons or UI objects which basically tells the thumb sticks not to enable. The problem with this is I’m having to set this up on every single UI element which isn’t ideal. I also have panels which the player can move around and I don’t want the thumb sticks to appear when the player is dragging the windows around the screen.

Does anybody have any ideas how one would tackle this? I’m scripting in C# for this project.

Did you try “IsPointerOverGameObject”?

https://docs.unity3d.com/ScriptReference/EventSystems.EventSystem.IsPointerOverGameObject.html

See the note at the bottom regarding touch.

1 Like

I saw that but was having trouble with what does what.
The following is from the bottom of the link you provided:

// Check if finger is over a UI element
            if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
            {
                Debug.Log("Touched the UI");
            }

I’m not sure how I could go about using this to say something along the lines of:
“Is the finger touching a child of the canvas?”
“If its not then enable the touch controls”
“if it is then do not enable the touch controls”

The bellow is what I’m currently working with:

if (Input.touchCount > 0)
        {
            Touch[] myTouches = Input.touches;
            for(int i = 0; i < Input.touchCount; i++)
            {
                Touch myTouch = Input.GetTouch(i);

                if (isDragging == false) <<<<<<< This is my current solution
                {
                    //Set start postition
                    if (myTouch.phase == TouchPhase.Began)
                    {
                        //Left Thumb Stick
                        if (myTouch.position.x < Screen.width / 2)
                        {
                            leftTouchLocStart = new Vector2 (myTouch.position.x, myTouch.position.y);
                            thumbStick_L.transform.position = (leftTouchLocStart);
                            thumbStick_L.SetActive (true);
                        }

                        //Right Thumb Stick
                        if (myTouch.position.x > Screen.width / 2)
                        {
                            rightTouchLocStart = new Vector2 (myTouch.position.x, myTouch.position.y);
                            thumbStick_R.transform.position = (rightTouchLocStart);
                            thumbStick_R.SetActive (true);
                        }
                    }

But with this method I have to set up each and every individual ui element to set isDragging to true if the pointer is over it.

GameObject playerRef;

    bool dragging;

    void Start ()
    {
        playerRef = GameObject.FindGameObjectWithTag ("Player");
        dragging = false;
    }
  
    public void StartDrag()
    {
        clickLoc = Input.mousePosition - gameObject.transform.position;
        dragging = true;
        playerRef.GetComponent<touchInput> ().isDragging = true;
    }
    public void StopDrag()
    {
        dragging = false;
        playerRef.GetComponent<touchInput> ().isDragging = false;
    }

I have very little experience with C# I’m struggling a little.

2 Likes

I’m thinking that you may need to keep track of fingerIDs that begin with IsPointerOverGameObject and not continue with any drag, if it began there. Then On touch ending/cancel (if applicable) remove the fingerID from such a list, if it’s there… I’ve never actually done this, but it sounds logical.

I don’t need the finger ID’s. I need a way of checking if the touch input is over a child of the canvas without having to implement it for each and every single button.
This is a video demonstrating the issue I’m having.

You can see that touch and multi touch is working fine. The trouble I’m having is the thumb stick appearing when I’m pressing other buttons.

You can see the window being dragged about without the thumb stick appearing. I’ve done this by setting the boo as shown in the previous post.
I’m looking for a way of implementing this kind of thing for each and every UI object without having to create a scrfipt for each and every UI object.
I don’t need to get each fingers ID for this. The thumb stick appearing behind a button when pressing a button is the problem I’m facing.

Cool… so, I was thinking… when touch began is true, and if it’s over a gameobject (like the window you’re dragging), you add the touchID to a list of “Do not follow these drags”…
then removing them at the end, etc, as I posted above… Did that not make sense before (or now?)

Oops. Tried to edit my post and messed it up.

Trying again…

Haven’t test this, just writing based on your example, I think something like this would work:

if (Input.touchCount > 0)
{
    Touch[] myTouches = Input.touches;
    for(int i = 0; i < Input.touchCount; i++)
    {
        Touch myTouch = Input.GetTouch(i);

        //Set start postition
        if (myTouch.phase == TouchPhase.Began && !EventSystem.current.IsPointerOverGameObject(myTouch.fingerId))
        {
            //Left Thumb Stick
            if (myTouch.position.x < Screen.width / 2)
            {
                leftTouchLocStart = new Vector2 (myTouch.position.x, myTouch.position.y);
                thumbStick_L.transform.position = (leftTouchLocStart);
                thumbStick_L.SetActive (true);
            }

            //Right Thumb Stick
            if (myTouch.position.x > Screen.width / 2)
            {
                rightTouchLocStart = new Vector2 (myTouch.position.x, myTouch.position.y);
                thumbStick_R.transform.position = (rightTouchLocStart);
                thumbStick_R.SetActive (true);
            }
        }
    }
}

It kind of makes sense to me. Though I know it’s me being stupid. I’m just having a hard time understanding it.

So these touchID’s you’re referring to… Are they references to the UI objects that are being touched? Or are they the actual touches them self’s (as in an index like finger 1 or finger 2)?

How would I make unity know which canvas children I want it to apply to?
So if for example:
I want to press a button and NOT have the thumb stick appear.
or
I have a map that’s overlayed on screen that I touch and DO want the thumb stick to appear.

I’m just having trouble getting my head around it…

But I do kind of get it… a little…

Thanks :stuck_out_tongue:

well, if you want to discriminate further, you have to add more logic, of course…
If you read the link about touchIDs you’d see they aren’t touch 0…n because those aren’t guaranteed to come in order, but what IDs do is guarantee that touchID 2 in began is the same touchID 2 that is dragging, etc… so you won’t drag an item that started somewhere you didn’t want it to start.
Someone between my post and yours maybe wrote an update script? It’s hard to tell b/c it’s quoted… but I figured you might have more that you didn’t show - so I wasn’t sure…
If you discriminate on what can cause it to move, then say the map from your example, don’t add that touch ID to the list of “Ignore drag/don’t show thumb sticks” whatever :slight_smile:

  • Otherwise it will apply to all gameobjects that can be hit by a raycast that’s on your camera. *

Oh, sorry, I meant to say this before… if the thumb controls or anything like that can only appear in touches Began, then you can forego the notion of the list entirely… I only added that feedback, in case you wanted to prevent movement in some script that maybe I didn’t see (you didn’t post).
If the thumb thing-a-ma-bobs can only appear in began, and then the player can only move or whatever you’re trying to prevent, beyond showing those, if those are already enabled… Only check in touches began, and forget about making a list… Sorry, should have said that … like 5 mins ago :slight_smile: No big deal lol

Ok that works. Now I need to figure out a way of making happen with only some of my UI objects.

One last question! :stuck_out_tongue:
IsPointerOverGameObject - Is this referring to any ui object? Can I specify what object?

I’ll keep fiddling with it. Both of you have been quite help full though. I’ve gotten a way better understanding of it.

Thanks!

I’m pretty sure that it considers any object that can be raycasted (based on the type of raycasters your camera has)… but my main experience is with the UI, using this & yes it’s any UI element that (again, can be raycasted to, pretty sure).

suggestion, if it’s only in Touches.Began, just check there if you want to specify further. Or whatever works for ya :slight_smile:

You’re welcome & good luck :slight_smile:

Ok it’s working great now. I was having trouble with the player moving even if the sticks weren’t visible which I think is what you were referring to earlier.

I’ve managed to get around this by just using “if (thumbStick_L.activeSelf == true)” to detect change in the movement values.

The right thumb stick basically controls the facing direction of the character and the direction the arm is pointing in.
I also have the “a” and “b” buttons as shown in the video. They basically making the arm do stuff like swing or perform a poking motion.

using the right thumb stick would basically allow the player to poke and swing in any direction. This is no longer the case.
I need to exclude the a and b buttons from the IsPointerOverGameObject check.

I think I know how I’m going to tackle it but we will see.

Cool, glad to hear it’s working pretty great. If you hit any snags along the way, feel free to post it :slight_smile:
Good luck :slight_smile:

1 Like