How to prevent 2-finger touch callback for 3-finger touch

I have implemented a touch camera with one, two, and three finger gestures that do different things like rotate, zoom, and pan. One and Two finger gestures work fine, but when I do three finger delta, the two finger position started callback is triggered. Not always, but enough to cause a zoom during pan sometimes to make the pan look jerky.

I did some debugging and noticed that Unity will go through each finger before checking to see if the next one is started/active. So my plan to check if the third finger is pressed in the second finger started function doesn’t do anything because the third finger will always be null until the second finger is done.

I was thinking to just keep a state to keep track of how many fingers is pressed and I update it in the callback and reset it in a LateUpdate, and during the LateUpdate, I check that state to determine if rotate/zoom/pan should be called. I was hoping to just use callbacks for my TouchCamera class without doing Update or LateUpdate. Is this possible?

I’m pretty sure you’re going to need to evaluate what you’re doing at the beginning of a one- or two-finger touch, if you also want to detect a three-finger touch. Computers, even Unity-running touchscreen computers, are quicker than you perceive. People’s fingers can’t always hit the glass at the same instant, and you’re probably getting called in that instant where two fingers were on the glass but the third finger didn’t actually hit the glass yet. When you said “not always” it’s a clue.

Two approaches:

(1) when you get a touch that you didn’t get in the frame beforehand, make a note of it in a state variable and don’t commit to doing anything until the next frame; this is similar to button “debouncing” to ensure you have the user’s true intent, but it can introduce delays between the initial touch and the time you can confidently take action

(2) when you start a two-finger touch action, make sure you save enough information to “undo it” if the next frame ends up having a three-finger touch instead; this will make the program the most responsive, but depending on what these different actions are, you will probably see a little flicker of two-finger actions taking place before getting reverted

I did something like the second idea. I have a boolean to keep track of if zoom had started. If I go into zoom and it’s set to false, I set it to true and store the current camera transform in an oldTransform variable. So if I enter the strafe (three fingers) call, I check the zoomStarted boolean and if it’s true, I reset the camera transform and set zoomStarted to false. Then do the strafe/pan movement on the camera and now things are zoom.

1 Like