• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by GrannySmith · Aug 26, 2013 at 11:02 AM · inputtouchpinch

Pinching invokes SingleTouch

I am developing an Augmented Reality App with a rather simple user interaction. The user is able to pinch to scale some 3D model and make single touches to loop through a set of animations for every 3D model.

Both works fine, but the problem is, when I am pinching then sometimes also a single touch is invoked when I end the pinching. THis is due to the fact, that you are not really able to lift both your fingers at the exact same time. This leads to the situation that after the pinching there is a time where only one finger remains on the touchscreen which further invokes a single touch.

Of course i dont want the user to invoke an animation nearly everytime he just wants to scale to model with pinching. I don't know how to tackle this problem. See my Code here:

     void Update ()
     {        
         for (int i = 0; i < Input.touchCount; i++) {
             if (Input.touchCount == 1 && Input.GetTouch (i).phase == TouchPhase.Ended) {
                 if (Input.GetTouch (i).position.x < Screen.width && Input.GetTouch (i).position.y < Screen.height) {
                     if (isLink) {
                         Application.OpenURL (link);
                     } else {
                         if (counter >= currentAnimations.Length) {
                             counter = 0;
                         }
                         currentObject.animation.Play (currentAnimations [counter]);
                         counter++;
                     }
                 }
             }
         }
 }
 
     void LateUpdate ()
     {
         DetectTouchMovement.Calculate ();
         if (DetectTouchMovement.pinchDistanceDelta != 0) {
             Debug.Log ("Transform " + currentObject.transform.localScale.x + "; initial " + trackables[trackablesCounter].getInitialScale().x + "; factored " + trackables[trackablesCounter].getInitialScale().x + factor * 15);    
         }
         // if zooming out
         if ((DetectTouchMovement.pinchDistanceDelta < 0 || Input.GetKey("q"))&& currentObject.transform.localScale.x > trackables[trackablesCounter].getInitialScale().x ) {
             logCurrentObject ();
             currentObject.transform.localScale = new Vector3 (currentObject.transform.localScale.x - factor, currentObject.transform.localScale.y - factor, currentObject.transform.localScale.z - factor);
             Debug.Log ("SCALE--------------: " + currentObject.transform.localScale.x + " 2: " + trackables[trackablesCounter].getInitialScale().x + factor * 15);
         }
         
         // if zooming in
         if ((DetectTouchMovement.pinchDistanceDelta > 0 || Input.GetKey("w"))&& currentObject.transform.localScale.x < trackables[trackablesCounter].getInitialScale().x + factor * 15) {
             logCurrentObject ();
             currentObject.transform.localScale = new Vector3 (currentObject.transform.localScale.x + factor, currentObject.transform.localScale.y + factor, currentObject.transform.localScale.z + factor);
             Debug.Log ("SCALE--------------: " + currentObject.transform.localScale.x + " 2: " + trackables[trackablesCounter].getInitialScale().x + factor * 15);
         }
     }

And here the DetectTouchMovement which i got from somewhere on the Internet, i forgot from where to be honest:

     const float pinchTurnRatio = Mathf.PI / 2;
     const float minTurnAngle = 0;
  
     const float pinchRatio = 1;
     const float minPinchDistance = 0;
  
     const float panRatio = 1;
     const float minPanDistance = 0;
  
     /// <summary>
     ///   The delta of the angle between two touch points
     /// </summary>
     static public float turnAngleDelta;
     /// <summary>
     ///   The angle between two touch points
     /// </summary>
     static public float turnAngle;
  
     /// <summary>
     ///   The delta of the distance between two touch points that were distancing from each other
     /// </summary>
     static public float pinchDistanceDelta;
     /// <summary>
     ///   The distance between two touch points that were distancing from each other
     /// </summary>
     static public float pinchDistance;
  
     /// <summary>
     ///   Calculates Pinch and Turn - This should be used inside LateUpdate
     /// </summary>
     static public void Calculate () {
         pinchDistance = pinchDistanceDelta = 0;
         turnAngle = turnAngleDelta = 0;
  
         // if two fingers are touching the screen at the same time ...
         if (Input.touchCount == 2) {
             Touch touch1 = Input.touches[0];
             Touch touch2 = Input.touches[1];
  
             // ... if at least one of them moved ...
             if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) {
                 // ... check the delta distance between them ...
                 pinchDistance = Vector2.Distance(touch1.position, touch2.position);
                 float prevDistance = Vector2.Distance(touch1.position - touch1.deltaPosition,
                                                       touch2.position - touch2.deltaPosition);
                 pinchDistanceDelta = pinchDistance - prevDistance;
  
                 // ... if it's greater than a minimum threshold, it's a pinch!
                 if (Mathf.Abs(pinchDistanceDelta) > minPinchDistance) {
                     pinchDistanceDelta *= pinchRatio;
                 } else {
                     pinchDistance = pinchDistanceDelta = 0;
                 }
  
                 // ... or check the delta angle between them ...
                 turnAngle = Angle(touch1.position, touch2.position);
                 float prevTurn = Angle(touch1.position - touch1.deltaPosition,
                                        touch2.position - touch2.deltaPosition);
                 turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle);
  
                 // ... if it's greater than a minimum threshold, it's a turn!
                 if (Mathf.Abs(turnAngleDelta) > minTurnAngle) {
                     turnAngleDelta *= pinchTurnRatio;
                 } else {
                     turnAngle = turnAngleDelta = 0;
                 }
             }
         }
     }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Fattie · Aug 26, 2013 at 12:12 PM

Hi Granny,

first it's worth noting that generally touch interface code is by no means easy

(eg ! http://answers.unity3d.com/questions/292333/how-to-calculate-swipe-speed-on-ios.html that on merely the issue of measurement)

Fundamentally, you just need a "stateful solution".

So, the computer should "know" if you were "just now" doing a two-finger move.

So do this. Have a variable "IWasDoingATwoFingerMove" which is a boolean.

Then carefully follow these THREE RULES......

1) whenever you are doing a two-finger move. Set IWasDoingATwoFingerMove to TRUE.

2) critically, whenever you see ZERO fingers on the glass, set IWasDoingATwoFingerMove to FALSE.

(Note - this means that "every frame" when the machine is just sitting there, it will set it to false. NO problem at all with that.)

3) Finally. somewhere you have code that says something like this:

 "if one finger ..
 then ..
 change my animation"

you must change it to this:

 "if one finger ..
 then ..
 if ( IWasDoingATwoFingerMove is true)
     {
     simply do nothing, return
     }
 else ..
     {
     change my animation, proceed as before
     }"

So that's how you do it. Hope it helps!

NB - I'm pretty sure your code is a bit messy; it may pay to start over from scratch. For example, it's very unlikely you need to use "LateUpdate" for any reason. That being said, if you can find "some, any" example code that does what you want -- fair enough. It's a pain in the ass programming this. So, just modify it exactly as I explain here and you'll solve the "phantom one finger" problem. Hope it helps!

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GrannySmith · Aug 27, 2013 at 07:56 AM 0
Share

Works perfectly. I feel ashamed that I didn't think of this myself.

avatar image Fattie · Aug 27, 2013 at 08:20 AM 0
Share

"Be ashamed of nothing" - F. Neitzsche

State-ful program$$anonymous$$g is, I suppose, the most difficult program$$anonymous$$g as you have to think over time (I mean, backwards forwards and all over the place in time), rather than linearly. Nothing to feel ashamed there!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

16 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

multiTouch problem when fingers close together (Bug?) 1 Answer

Mouse and Oculus Touch Controller Inputs 0 Answers

Input.GetTouch SOMETIMES not registering on iOS 0 Answers

Simultaneous touch inputs do not always work 0 Answers

Apple touch device input touch question 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges