Search Unity

Input.Touches - Simple Gesture Solution

Discussion in 'Assets and Asset Store' started by Song_Tan, Apr 28, 2012.

  1. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
    Hey,

    Can someone please tell me what is the difference between OnSwipe and OnSwiping events?
    It is not clear from the documentation.

    Also, the OnSwiping event has a warning that I do not understand:
    Please note: that the swipe events passed in this instance are not subject to all the specified parameters in
    SwipeDetector.cs and thus may not be a valid event.


    Thanks.
     
  2. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    onSwipeE is only called once in one swipe
    onSwipingE is called in every frame through out the the whole swipe event, until onSwipeEndE is called

    in a nutshell, during the swipe event, the events are trigering in following order:

    onSwipeStartE
    onSwipingE
    .
    .
    .
    onSwipeEndE ----- onSwipeE (if the swipe full-filled the given parameter in SwipeDetector.cs)

    Please note that none of the onSwipeStartE, onSwipingE and onSwipeEndE is subject to the configurable in SwipeDetector.cs

    I'm not sure what is the reason behind that warning. I've never come across it. Does it happen with your own script or with the example script? Perhaps you can send me your code and I can have a look.
     
  3. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
    Thanks.

    The warning is from the documentation itself, not from the code.
     
  4. Schiffy

    Schiffy

    Joined:
    Jul 22, 2012
    Posts:
    4
    Songtan,

    Is it possible for a GameObject to differentiate between a single-tap and a double-tap? It appears that your library does not use a time-out to make this distinction; rather, it just fires each touch event as it comes. This could be a very useful option to enable, as someone might want a GameObject to behave differently when it is single-tapped vs. double-tapped. Please correct me if your library supports this, because I'm about to write this functionality (and would rather not re-invent the wheel)!

    Code (csharp):
    1.  
    2. void OnEnable() {
    3.     InputManager.onMultiTapE += OnTap;
    4. }
    5.    
    6. void OnDisable() {
    7.     InputManager.onMultiTapE -= OnTap;
    8. }
    9.    
    10. private void OnTap (Tap tap) {
    11.     if (tap.count == 1) {
    12.         print ("Single tap");
    13.     } else if (tap.count == 2) {
    14.         print ("Double tap");
    15.     }
    16. }
    17.  
     
  5. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    It does have a time-out to reset any multi-tap event. There's a maximum interval time for a multi-tap event, if a subsequent tap doesnt come within that duration, the tap count is reset. Your code is exactly how the multiTap event intended to be used, that is how the it's done in the example code TapDemo.cs.

    There is an option to limit how high you tap count can go. you can limit it to single/double tap if triple or more-tap is not used. In that case, any tap count that exceed the limit will be reset and recount from 1.

    I'm not really sure if I understand/answered your question fully tbh. If you have any idea reagrading how I can make things easier and better, please let me know.
     
  6. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Just a quick notice that a new update version1.1.2 has been uploaded and now live on AssetStore. Nothing major except a documentation overhaul. Many thanks to DannyB and Lance(Nekoyoubi) for the documentation update! And many thanks to the all the feedbacks and kind review!!

    If you are interested in the library, feel free to contact me to get a copy for the documentation. :)
    Following is the version change:


    General Change:
    - documentation overhaul.​
    Bug Fixes:
    - releasing finger on mobile device no longer triggered a spike in onDraggingE and onDraggingEnd
    - pre-made gesture prefab is no longer missing BasicDetector.cs​
     
    Last edited: Jul 25, 2012
  7. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
  8. Schiffy

    Schiffy

    Joined:
    Jul 22, 2012
    Posts:
    4
    Songtan,

    While I acknowledge that Flash is still in a developer preview, I'm curious to know if you plan on releasing a version of Input.Touches supports Flash's current state.

    Thanks,
     
  9. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    @Schiffy, Unfortunately no, at least for the time being. Given the unity4 seems to ready to release anytime now, I would prefer to wait for it and see how it goes.
     
  10. Schiffy

    Schiffy

    Joined:
    Jul 22, 2012
    Posts:
    4
    Songtan,

    That's completely understandable :)

    Thanks for replying,
     
  11. ShawnT

    ShawnT

    Joined:
    Aug 15, 2012
    Posts:
    3
    Is there any way to get the two touch points for a pinch event? I would like to compute the midpoint (i.e. midpoint = (pos1 + pos2) / 2) and then use that to see what object in the scene that the user is trying to pinch.

    Thanks
     
  12. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    There no direct way to do this unfortunately. You can either modify the code or try this in your own code.

    Code (csharp):
    1.  
    2.     void OnPinch(float val){
    3.         Vector3 point1=Input.touches[0].position;
    4.         Vector3 point2=Input.touches[1].position;
    5.         midPoint=(point1+point2)/2;
    6.     }
    7.  
    Let me know if you need more information or help on this topic. You can email me directly. :)
     
  13. ShawnT

    ShawnT

    Joined:
    Aug 15, 2012
    Posts:
    3
    Thank you for the quick response, I actually modified the code to return pos1 and pos2 in onPinchE and it seems to work. Perhaps in your next update you can consider adding that feature?
     
  14. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I'll consider doing that. However I dont see next update happening so soon. We'll see.
     
  15. CiroContns

    CiroContns

    Unity Legend

    Joined:
    Jan 28, 2008
    Posts:
    115
    Hi Song Tan,
    I'm using your library and I'm generally satisfied with it, it was worth the money.

    Unfortunately, I switched from version 1.0 to 1.1.2 (latest) and everything is broken for touch input in my game.
    I was using onMouse1DownE to recognize both mouse input and touch input (for a single touch). This because before, even finger touches would fire onMouse1DownE, so I just needed that to capture both kinds of input.

    Now, since I updated, the game works fine in the editor but not anymore on the iPad. Touches seem not to fire onMouse1DownE anymore, am I correct?
     
  16. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Sorry for the delay.

    Fyi, as of version1.1, touches does not fire mouse event anymore. But if you need to listen to both mouse and touch event for the same purpose, simply subscribe to both onMouse1DownE and onTouchDownE and have them calling the same function.
     
  17. CiroContns

    CiroContns

    Unity Legend

    Joined:
    Jan 28, 2008
    Posts:
    115
    Thank you so much, that's how I suspected. It's ok because it's more logical this way.

    Another question:
    I'm using a "drag and drop" functionality, but I want to tie the same mechanism to a swipe. Basically, I want the player to be able to do the same thing by swiping, or by clicking and releasing the mouse (or touch).

    If I register for the onSwipeE, I see that a swipe is registered in two ways: One is if I release the touch, and the other is when I change direction (since you made it so multiple swipes can be chained without releasing).
    My problem is that when I swipe and release the touch, also the drag-and-drop functionality triggers, since the onTouchUpE event is fired before the onSwipeE.
    This way the swipe doesn't have the desired effect, since for the game logic the user has already released the touch before the swipe happens.

    Is there a way to prevent this? How can I detect the swipe even if the user hasn't released the touch yet?
    Thanks for the support!
     
  18. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Well, please check the documentation. I have added a series of new events such as onSwipeE, onSwipingE and onSwipeEndE in the new version. Naturally you are looking for onSwipingE which would fire in every frame while a swipe is taking place. Hope this helps. :)
     
  19. CiroContns

    CiroContns

    Unity Legend

    Joined:
    Jan 28, 2008
    Posts:
    115
    It wasn't much help, because OnSwipingE and OnSwipeStart are 'fake' events, since they can fire even if the swipe has just started and so we don't know yet if the user is going to swipe or not.

    My problem is that I cannot get a swipe event before the mouse/touch is released. The only way would be to subscribe to OnSwipingE and save the SwipeInfo every frame, overwriting the old. Then, in the OnTouchUpE handler, analyze the saved SwipeInfo object and say "was it a real swipe?", and act accordingly (i.e., if it's a good swipe, I perform the swipe behavior and not the release button one).
     
  20. CiroContns

    CiroContns

    Unity Legend

    Joined:
    Jan 28, 2008
    Posts:
    115
    I elaborated a small hack which should be ok for my case.

    I added a new boolean field in the SwipeInfo class, called "isValid". Since the swipe routine is stopped if the direction change is too great, swipe is too slow, or takes too much time, the only thing I need to check in a onSwipingE for a swipe to be useful is the distance that the finger/mouse travelled so far.
    To do this, in the SwipeDetector I modified the Swiping function like this: (line 4 is my edit)

    Code (csharp):
    1. void Swiping(Vector2 startPos, Vector2 endPos, float timeStartSwipe, int index, bool isMouse){
    2.     Vector2 swipeDir=endPos-startPos;
    3.     SwipeInfo sw=new SwipeInfo(startPos,endPos,swipeDir,timeStartSwipe,index,isMouse);
    4.     if((swipeDir).magnitude >= minDistance) { sw.isValid = true; }
    5.     Gesture.Swiping(sw);
    6. }
    This way in my game I can save the SwipeInfo every frame, and on the release of the button, I can do:

    Code (csharp):
    1.  
    2. private SwipeInfo sw;
    3.  
    4. private void OnSwiping(SwipeInfo sw)
    5. {
    6.     savedSwipe = sw;
    7. }
    8.  
    9. private void OnRelease(Vector2 tapInfo)
    10. {
    11.     if(savedSwipe.isValid)
    12.     {
    13.         //Use the saved swipe data
    14.     }
    15. }
    16.  
    And be sure that the swipe, although SwipeEndE has not fired yet, was valid.
    What do you think?
     
    Last edited: Aug 29, 2012
  21. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Sorry I didnt understand that the validity of the swipe would be an issue.

    What you are suggesting could be one way to do it. But you should have some sort of timer on the OnSwiping to clear the savedSwipe. Since by the swipe might goes invalid and stop firing the event if the user hold their finger for a while after the swipe. If that's the case, by the time OnRelease is called whatever swipe info you have saved would have gone invalid. (not sure If I explain this well enough)

    Alternatively, you can use a coroutine and yield in OnRelease so that the onTouchUpE delagate only gets execute in the next frame. By then, you should have received a swipe event if there's one. The user shouldnt be able to notice the lag if it's only 1 frame.
     
    Last edited: Aug 29, 2012
  22. CiroContns

    CiroContns

    Unity Legend

    Joined:
    Jan 28, 2008
    Posts:
    115
    It's not a real issue, but it might be useful to have it.

    I clear the savedSwipe at the end of the OnRelease function, since once the user releases the finger any new swipe belongs to another finger press.
    If the user swipes, stops the finger, then releases the touch, as you say it would not be a valid swipe, which is fine with me because I always want the swipe to be a quick flick on the screen (like kids do when playing with marbles on the sand :D), so I always use the swipe data only if it's followed by a touch release.

    Thanks for the help, I still love the library and it's proving very useful :)
     
  23. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Thanks for the kind words. And many thanks indeed for suggesting the solution. :)
     
  24. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,162
    @songtan is it possible to use one folder in your package? when i import your package it generates inputTouches and Plugins folder. can you put your plugins stuff in inputTouches folder?
     
  25. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Unfortunately I have to those scripts in Plugins folder for the purpose of code compilation order. Otherwise anyone who use .js wont be able to access anything from InputTouches since it's coded in C#.

    If you are using C#, you can manually drag the Plugins folder into InputTouches folder. You may get an error from the example script Listener.js but you can delete that.
     
  26. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,162
    now there are pm actions. i did all on that page.i used short tab action but it does not work. it work with mouse pick event of pm. do you have any idea?
     
  27. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Do you mean short tap? Is it just short tap alone or all of the vent is not working?

    Either way, I'm afraid the help I can give is limited. I dont know how the inner working of pm. What I can say it make sure you have "Gesture" prefab in your scene and the relevant components needed on the prefab are enabled (TapDetector.cs for short tap). Anything beyond that, you will have to ask the pm team.
     
  28. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,162
    i found solution;

    http://hutonggames.com/playmakerforum/index.php?topic=1938.0
     
  29. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Nice. Thanks for sharing...
     
  30. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    572
    Hi, I need a little help, I want to detect Up/Down/Right/Left swipe.
    How can I do it?
     
  31. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    SwipeInfo is passed along with angle of the swipe. That is started at +ve x-axis of the screen in counter clockwise. So you can determine the direction based on that. The code could look like this:

    Code (csharp):
    1. void OnEnable(){
    2.     Gesture.onSwipeE += OnSwipe;
    3. }
    4.  
    5. void OnDisable(){
    6.     Gesture.onSwipeE -= OnSwipe;
    7. }
    8.  
    9. //detect swipe direction
    10. void OnSwipe(SwipeInfo sw){
    11.     if(sw.angle>=45  sw.angle<135){
    12.         Debug.Log("swipe up");
    13.     }
    14.     else if(sw.angle>=135  sw.angle<225){
    15.         Debug.Log("swipe left");
    16.     }
    17.     else if(sw.angle>=225  sw.angle<315){
    18.         Debug.Log("swipe down");
    19.     }
    20.     else{
    21.         Debug.Log("swipe right");
    22.     }
    23. }
     
  32. captain00000000

    captain00000000

    Joined:
    Oct 17, 2009
    Posts:
    3
    I try Infrared multi-point touch at win7.
    communication :Tuio UDP (T) and Flash XML (F).
    but did not touch reaction ,why?
     
  33. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Terribly sorry, but this framework only work for those hardware supported by unity by default, ie. i-Device and android device. I dont remember saying otherwise.
     
  34. captain00000000

    captain00000000

    Joined:
    Oct 17, 2009
    Posts:
    3
  35. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Very sorry again, I meant the gesture would work when performed using mouse. I'll change the description.
     
  36. gregmax17

    gregmax17

    Joined:
    Jan 23, 2011
    Posts:
    186
    Is there a way to detect if the user did a clockwise/counter clockwise circular rotation gesture?
     
  37. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    If you meant 2 finger twisting motion (as the gesture normally seen used to rotate certain object in virtual 3D environment), yes.

    For a single finger to draw a circular shape on screen, I'm afraid not.

    Hope that answer your question.
     
  38. gregmax17

    gregmax17

    Joined:
    Jan 23, 2011
    Posts:
    186
    I am using PlayMaker and the Input.Touches plugin which was provided on the PlayMaker website. I have the swipe left and right gesture working probably. How do I get the rotate and the direction of the rotation? Also, is there anyway to make sure the rotate and the swipe left/right don't conflict with one another?
     
  39. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    To be honest, I'm not sure. I'm looking at the event list at PlayMaker website, it doesn't seem to have a rotate event. On the other hand, it definately have it cover because there's "Input Touches Get Gesture Magnitude" specifically for rotate and pinch event under "Custom Action List". Perhaps you should ask the PlayMaker team on this? If you manage to get the event, the direction of the rotation is indicated by the direction of the value. +ve value for clockwise and -ve value for counter-clockwise (it could be the other way round, apology again for not sure).

    In my experience, it's quite difficult to have these two conflict with each other. If you must, you can lower the allowance of direction change and increase the minimum speed for swipe. Rotate tends to have a very dramatic direction change and much slower than swipe.

    Hope that helps.
     
  40. kblood

    kblood

    Joined:
    Jun 20, 2012
    Posts:
    92
    Hi,

    I am wondering if this is possible? It seems it is, but I have not seen it done. It is the D Pad example I am thinking of and I am just not sure how yet. I am coding in JavaScript, so it takes a while longer for me to understand the examples. I am trying to make it possible to use this:

    http://developer.sonymobile.com/2011/02/28/xperiaplaytipsbyangrymobgames/

    To control a game. I will probably need to use more than just your scripts to make this possible, but I just want the buttons to work first, and the raycasting solution seems to be the only real one anyway. You have not made an example that uses meshes instead of guitextures as control input, is there a good reason for that, or just because it seems too complicated for something so simple?

    Thanks for the input touches. So far I have been using it to make simple touch interfaces in a much faster.
     
    Last edited: Sep 16, 2012
  41. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I'm not sure to which feature in the article you are refering to that you are wondering if it's possible. All or it?

    As far as I can tell, everything is possible. But of course you will need more than the example script. InputTouches just provide you a solution to get the touch data, it shouldnt restrict you in anyway to implement your control.

    Yes, I have not used meshes in the example. Using GUITexture is more straight-forward solution. By using mesh, you have to use a secondary camera for the UI element so the UI element stay in fixed position on screen when you main camera moved for some reason. And you can avoid using raycasting if you are using GUITexture.

    At any rate, let me know what are you struggle with. I'll be happy to provide you a template which you can use in your game.
     
  42. gregmax17

    gregmax17

    Joined:
    Jan 23, 2011
    Posts:
    186
    how do I test a 2 finger rotate in the unity3d editor?
     
  43. Count_Zer0

    Count_Zer0

    Joined:
    Sep 12, 2012
    Posts:
    6
    The RTSCam script is great!

    Unfortunately right-mouse button click does not allow camera pan in web browsers (Chrome or Safari), it brings up a Unity player menu offering to go to full-screen.

    Scroll-wheel does zoom in Chrome browser, though it does not seem to respect the 'Zoom Speed Modifier' attribute. Scroll-wheel does NOT zoom in Safari, however.

    Is there any easy way to attach Middle-mouse button to camera panning or some other re-mapped solution if right-mouse button is reserved for the Unity webPlayer menu?
     
  44. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    The only way to test it is to use a Unity Remote on a touch device.

    Please check link. It shows you how to disable the right-click pop up. Alternatively you could use other mouse button like you suggested. But as of now the library only support mouse button 1 and 2. You can add new middle mouse button by adding this section of code to line215 in DragDetector.cs:

    Code (csharp):
    1.         if(Input.GetMouseButtonDown(2)){
    2.             if(!mouseIndex.Contains(2)) StartCoroutine(MouseRoutine(2));
    3.         }
    4.         else if(Input.GetMouseButtonUp(2)){
    5.             if(mouseIndex.Contains(2)) mouseIndex.Remove(2);
    6.         }
    7.  
    And of course to add change panning to work with middle mouse for RTSCam.cs, just change line 75 from

    Code (csharp):
    1. if(dragInfo.isMouse  dragInfo.index==1) OnMFDragging(dragInfo);
    to

    Code (csharp):
    1. if(dragInfo.isMouse  dragInfo.index==2) OnMFDragging(dragInfo);


    I dont seem to have this problem. I did a quick google search and this could be a bug on the browser with Unity. Not sure but I cant really help. If you look at the code in RTSCam.cs, the mouse wheel input is not really part of the library. It's the very generic default Input.GetAxis("Mouse ScrollWheel"). Very sorry but I'm not really sure how can I help here.
     
  45. richardjazz

    richardjazz

    Joined:
    Sep 22, 2012
    Posts:
    1
    i recently puchased this, and getting error in javascripting :

    SpriteAnimater.js(185,18): BCE0005: Unknown identifier: 'Gesture'.

    what is the problem ?
     
  46. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
    You probably didn't grab the Gesture prefab to the scene.
    You can either drag the prefab provided by the package, or create your own empty object and attach the Gesture script to it.
     
  47. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Thanks Danny. :)

    @richardjazz,

    I will need more information to know exactly what went wrong. Where is the js file that causes error (SpriteAnimater.js) being placed, under which folder? Fyi, It cannot be placed in any folder under the hierarchy of folder named "Plugins" or "Editor". To be safe, please try placed it along the js example. Finally please do not move the InputTouches files in folder named "Plugins" or indeed the folder itself.

    Hope this helps.
     
    Last edited: Sep 22, 2012
  48. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    572
    Is there a way to recognize "circle"?
     
  49. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Unfortunately, no. The library doesnt recognise any shape, only relatively standard input gesture.
     
  50. Mars91

    Mars91

    Joined:
    Mar 6, 2012
    Posts:
    572
    I'm trying to instantiate a Prefab using touch up position here's my code
    Code (csharp):
    1.  
    2. function OnTouchUp(pos : Vector2){
    3.     var ray: Ray = GUICamera.ScreenPointToRay(pos);
    4.     var hit : RaycastHit;
    5.     if(Physics.Raycast(ray, hit, Mathf.Infinity)){
    6.         if(hit.collider.gameObject == gameObject  startForcingStove){
    7.             if(hittedTime < needToGeyKey){
    8.                 if(soundToPlay){
    9.                     audio.PlayOneShot(soundToPlay);
    10.                 }
    11.                
    12.                 hittedTime++;          
    13.                 GoForceStove(hittedTime, pos.x, pos.y);
    14.             }
    15.         }
    16.     }
    17. }
    18.  
    Code (csharp):
    1.  
    2. function GoForceStove(hitted : int, posX : float, posY : float){
    3.     if(hittedTime >= 1  hittedTime < 5){
    4.         Instantiate(particlePrefab, Vector3(posX, posY, 2.487528), Quaternion.identity);
    5.     }
    6. }
    7.  
    The problem is that there's no prefab in game . . .