When I run my app on Android, the first finger touch calls Input.GetMouseButtonDown(0)
and the second touch calls Input.GetMouseButtonDown(1)
.
I want to override GetMouseButtonDown(0)
in some cases- so the second finger (1) touch will become the first (0) and I don’t know how to do it.
Either this or how to force mouseButtonUp
on the first finger touch- I want to remove this first “click” from the system so it’ll not use Input.mousePosition
in a case of 2 touches.
Why?
I’m creating a paint app when the user can draw lines.
There is an area when the user can paint (in a rectangle) and an area where he shouldn’t, I know how to detect when pressed on an unwanted area.
But sometimes the palm of my hand creates unwanted first touch Input.GetMouseButtonDown(0)
on the unwanted area (without Input.GetMouseButtonUp(0)
) and when I start to draw a line
Input.mousePosition
gets the average of both touches, so I just want a way to remove a “down” touch/click from the system. Or another way to solve my problem.
Simply don’t use GetMouseButton Up / Down or Input.mousePosition at all. Those are ment for “mouse input” on desktop systems. Unity just emulates those events based on touch events so it’s easier to reuse certain methods / classes on mobile devices. This emulation does only support a single touch.
You should exclusively use the touch input (Input.touches or touchCount + GetTouch). Each touch has a fingerId which identifies that touch from the beginning to the end. You should not rely on any particular order of the touches in that “Input.touches” array. Always use the fingerId for reference.
The usual approach is to store the fingerId in a variable when the touch.phase is “Began” and on all other event types you would always check against the fingerId.
Some pseudo code:
private int drawingFinger = -1;
foreach(var t in Input.touches)
{
if (t.phase == TouchPhase.Began)
{
if (t.position is inside drawing area)
{
drawingFinger = t.fingerId;
// handle additional "down" event things
}
}
else if(t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled)
{
if (t.fingerId == drawingFinger)
{
drawingFinger = -1;
// do your "up" event things
}
}
}
Note: don’t rely on certain hardcoded ID numbers. Only use them “relatively”. So you get the ID in Began, store it while the touch is still there and mark it as invalid (-1) when the touch ended. Usually fingerIDs are allocated in sequence but as i said you shouldn’t rely on it. Due to some bugs old fingerIDs might “get stuck” (happend mainly when you exit the app while still 2 or more touches where active).