Charlie Tobler
Charlie Tobler

Reputation: 51

In Unity, trackpad tap only counts as mouse down, and no mouse up

I am having an issue where when I hit play to test my game in the Unity Editor, I have some functions that execute on OnMouseUp(), and I noticed that sometimes they weren't working, or were executing at weird times. When I started debugging, I noticed that when I click with a trackpad, it is normal, but when I tap on the trackpad, it registers a mouse down event, but not a mouse up event. So technically the user can "click" on an object without triggering a mouse up event (Please don't tell me to use a mouse down event, it is not possible for what I am trying to do).

I don't doubt we will have users playing on a laptop with the trackpad, so I don't want this to be an issue for them. Could I fix this by using Unity's touch system in congruence with mouse clicks?

I am on a Mac if that helps at all. We will be releasing the game on Windows, Mac, iOS and Android. Let me know if you need any more information. I am just trying to get general information. I did a lot of research, but I didn't really find anything quite related to what I am dealing with.

Thanks in advance for any help you can provide!

EDIT:

I have been working on this issue, and have a related question. Someone posted a link, but I guess it got taken down. The link was here: Mouse up vs. touch up in Unity. I think my issue might be related. I decided to try using Unity Touch system to see if I could fix it. Here is my code (it is a script to create swipe gesture functionality):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Ibuprogames.CameraTransitionsAsset;

public class SwipeColliderScript : MonoBehaviour {

    [HideInInspector]
    public float mouseDistance;
    Vector3 lastPosition;
    bool trackMouse;
    [HideInInspector]
    public bool isSwipe;
    [HideInInspector]
    public bool swipeRight;
    [HideInInspector]
    public bool swipeLeft;
    private Touch touch;

    private void Awake()
    {
        swipeLeft = false;
        swipeRight = false;
    }

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

        if (Input.GetMouseButtonDown(0) && Input.touchCount > 0)
            {
            touch = Input.GetTouch(0);
            Debug.LogError("Touch activated");
            }

        if (Input.GetMouseButtonDown(0) || touch.phase == TouchPhase.Began)
            {
                trackMouse = true;
                isSwipe = false;
                lastPosition = Input.mousePosition;
                Debug.LogError("Mouse or tap down registered");
            }
            else if (Input.GetMouseButtonUp(0) || touch.phase == TouchPhase.Ended)
            {
                trackMouse = false;
                Debug.LogError(@"Mouse held for " + mouseDistance + "pixels!");

                mouseDistance = 0;
            }

            if (trackMouse)
            {
                Vector3 newPosition = Input.mousePosition;
                mouseDistance += (newPosition.x - lastPosition.x);

                if (mouseDistance > 20 || mouseDistance < -20){
                    isSwipe = true;
                }

                if (mouseDistance > 20)
                {
                    swipeLeft = true;
                    swipeRight = false;
                }
                else if (mouseDistance < -20)
                {
                    swipeRight = true;
                    swipeLeft = false;
                }

                lastPosition = newPosition;
            }
       }
  }

I think a solution similar to this will work, but my issue right now is that Debug.LogError("Mouse or tap down registered") is firing every frame, which in turn means that touch.phase == TouchPhase.Began is apparently true all the time, even when my finger isn't on the trackpad. Why would this be? touch is only being created when touchcount > 0, so I don't see why this should be firing before I ever put my finger on the trackpad. Can anybody help with this?

EDIT 2:

I tried adding this to the Awake function:

if (SystemInfo.deviceType != DeviceType.Handheld)
        {
            Input.simulateMouseWithTouches = false;
        }

I then created some debugging logic to determine whether a trackpad tap was a touch or mouse down (I should have done this first, but I am a noob and it took my this long to realize that).

It is a mouse down.

I don't really know what to do know. How do I differentiate between trackpad taps and trackpad clicks if they both function as mouse down?

Please help!

Charlie

Upvotes: 1

Views: 2612

Answers (1)

Charlie Tobler
Charlie Tobler

Reputation: 51

Well, I came to the conclusion that there was no way I would be able to tell whether a mouse down came from a trackpad tap-to-click or a mouse click, so I decided to rework my script to only work with the Unity touch system. That way gestures only work on handheld devices, and there is no issue with the trackpad since I am using touch instead of mouse down. Here is my script if you are interested. I didn't change all of the names of the variables, but all the pertinent bits have been changed to use touch. If you see any errors I missed, please point them out to me. Hope this helps someone:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Ibuprogames.CameraTransitionsAsset;

public class SwipeColliderScript : MonoBehaviour {

    [HideInInspector]
    public float mouseDistance;
    Vector3 lastPosition;
    bool trackMouse;
    [HideInInspector]
    public bool isSwipe;
    [HideInInspector]
    public bool swipeRight;
    [HideInInspector]
    public bool swipeLeft;

    // Update is called once per frame
    void Update()
    {
        if (SystemInfo.deviceType == DeviceType.Handheld)
        {
            if (Input.touchCount == 1)
            {
                Debug.LogError("touch down registered");
                Touch touch = Input.GetTouch(0);

                if (touch.phase == TouchPhase.Began)
                {
                    trackMouse = true;
                    isSwipe = false;
                    lastPosition = touch.position;
                    Debug.LogError("Mouse down registered");
                }
                else if (touch.phase == TouchPhase.Ended)
                {
                    trackMouse = false;
                    Debug.LogError(@"Swipe held for " + mouseDistance + "pixels!");

                    mouseDistance = 0;
                }

                if (trackMouse)
                {
                    Vector3 newPosition = touch.position;
                    mouseDistance += (newPosition.x - lastPosition.x);

                    if (mouseDistance > 20 || mouseDistance < -20)
                    {
                        isSwipe = true;
                    }

                    if (mouseDistance > 20)
                    {
                        swipeLeft = true;
                        swipeRight = false;
                    }
                    else if (mouseDistance < -20)
                    {
                        swipeRight = true;
                        swipeLeft = false;
                    }

                    lastPosition = newPosition;
                }
            }
        }
     }
  }

Upvotes: 1

Related Questions