Reputation: 51
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
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