playMaker

Author Topic: Get Touch Info - reports incorrect Delta information?? [FIXED]  (Read 10511 times)

IPete2

  • Playmaker Newbie
  • *
  • Posts: 23
Hi Alex,

Not sure if this is what I am seeing.  I found using Get Touch Info reports Delta Position Vector but when I ask for the DeltaX it seems to report the actual x position found in Store X.  So this makes it impossible to work out which way a touch has moved.  The Swipe Gesture does not respond quickly currently so I have been trying to mix the other available commands to make something similar.

IPete2.
« Last Edit: October 06, 2011, 04:08:27 PM by alexchouls »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 3987
  • Official Playmaker Support
    • LinkedIn
Re: Get Touch Info - reports incorrect Delta information??
« Reply #1 on: May 08, 2011, 03:25:40 AM »
I'll take a look. The actions just accesses touch.deltaPosition, but maybe something else is going on...

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Get Touch Info - reports incorrect Delta information??
« Reply #2 on: May 10, 2011, 02:36:32 AM »
Hi,

 Are you testing on the real device or via the Unity remote app? It makes a huge difference with input precision and timing ( you actually have to write some junk if you use the unity remote often because straight code sometimes doesn't event work).

 Bye,

 Jean

IPete2

  • Playmaker Newbie
  • *
  • Posts: 23
Re: Get Touch Info - reports incorrect Delta information??
« Reply #3 on: May 10, 2011, 01:53:28 PM »
I tested on device, but I'm also polling the Delta X and printing it to the debug.log and its the same as the Store X, which I also print out. There should be a difference I would have thought.


jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Get Touch Info - reports incorrect Delta information??
« Reply #4 on: May 11, 2011, 01:03:07 AM »
Hi,

Could you share or describe precisly so that we can reproduce? I'd be happy to run your sample and see if I get the same and maybe spot something,
 

Bye,

 Jean

IPete2

  • Playmaker Newbie
  • *
  • Posts: 23
Re: Get Touch Info - reports incorrect Delta information??
« Reply #5 on: May 11, 2011, 05:29:42 PM »
Hi Jean,

This is why and what I need to achieve:

I need a swipe gesture presents data as the swipe is occurring.  The current Swipe Gesture doesn't feedback until the finger lifts off the screen, I have no idea why it does that, but in my mind that is not useful.  The information from the direction of swipe should be available and adjustable to the point that I can calculate the speed of a menu moving as a result of a swipe by a single finger.  But I need to move the menu as the finger swipes, not once it has lifted.

So by combining some maths with the Get Touch Info I tried to make my own swipe gesture -  the way I need it.

To re-create this, simply create a new scene. Add FSM to an object such as a camera. Add variables, Vector3 StorePos, StoreX as a float variable, DeltaX as a float variable.  Wire these in place on the FSM to the matching settings:

Store Position : StorePos
Store X: StoreX
Delta X : DeltaX

Set to Debug that State, plug in the Unity Remote to a device and run.  Test swipes and look at Debug Log. 

All the StoreX figures and DeltaX figure match when I do this, which means I cannot calculate which way a swipe is moving, or how fast it is moving.  I would expect the DeltaX to be different at some stage, but it just always seems to replicate the StoreX value.  Perhaps we need some form of time delay for the Delta and no repeat until that data has been stored to be used by the developer?

Anyway I hope this helps clarify what I am trying to do, how and why.  If there is a better way please let me know.  interactive@studioliddell.com or peter@smartscreenuk.com

Best regards,

Peter -  IPete2.



jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Get Touch Info - reports incorrect Delta information??
« Reply #6 on: May 12, 2011, 03:32:16 AM »
Hi Peter,

 I have implemented such live swipe but it's all scripted at the moment ( done before the Playmaker era :) ), so I have the logic but not done in Playmaker.

How do you expect the swipe to behave when the user releases the touch? currently I detect swipe speed and travel and validate the swipe based on these two params so that the swipe lands naturally on  the new content or back if speed or travel is sufficient. Or do you simply need some kind of scrolling? How do you want the scrolling or swiping limits to behave? with elasticity or with hard bounds?

Also, how do you expect the swipe value to range from and to and compare to what? Do you want to swipe the screen or a gui component or part of the screen?

I am currently unsure if it actually should be done in Playmaker or as an action. As an exercice, yes, but in a real world project, I would suspect such system  to be a lot easier to implement and reuse properly as an action, at least until sub fsm is out, tho a template could be used.

Allow me few days to get back to you with at least a basic action or fsm.


 Bye,

 Jean

IPete2

  • Playmaker Newbie
  • *
  • Posts: 23
Re: Get Touch Info - reports incorrect Delta information??
« Reply #7 on: May 12, 2011, 05:21:24 PM »
Wow Jean,

Sounds amazing so far, and thank you for your support, it is very kind of you to assist in this way.  :)

What I need to be able to implement is a swipe which allows a series of 'cards' like 'cover flow' to move through screen, from one end of a range of objects (to be determined as objects in a selection menu) to the other.  They need to stop and not be able to move at each end stop.  So if it were numbers 1 to 20, 1 would not be able to scroll passed the last centred number '0'  to reveal lower numbers such as -1, -2.  The swipe would do no more work in that direction, equally, when swiped to reveal 1,2,3,4,5,6,7...16,17,18,19,20 - at 20 (in the centre) it would no longer scroll off to try to reveal bigger number. It would not be swipable and it would not move.  1 and 20 would be 'end stops'.  

So, I need to be able to determine from the swipe, how much movement and in which direction the cover flow like objects will move.  Currently the swipe gesture in Playmaker does not generate a response until the finger has lifted off the screen, this is too slow for my use.  I need it to move with the finger and have some amount of momentum once the finger has lifted off the screen, to allow movement onto the next object or settle back to the last object if not enough swipe energy.  So what you have sounds like it would work fine.  A big swipe should in a direction should result in a faster movement in the direction of the swipe.

Ideally I would like to swipe the screen, not a gui component.  The player will touch the sprite/button which make up the main cover flow objects to select it or activate it once it has settled.   I need to be able to make the range move just one at a time for accuracy and generally swipe with some momentum, to move through a series of objects in one swipe.

I intend to use EZGui for the button objects, these will move through the screen revealing all the options in my range.  I need three objects on screen at a time, one left, one centre, one right.

I have tried a few different ways to get something slick working and I have failed.  I did try different methods, code and PlayMaker, but could not get a good enough result.  

Any help with this either as a PlayMaker fsm or code would really be appreciated.

Thanks again!

IPete2.
« Last Edit: May 12, 2011, 05:23:06 PM by IPete2 »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Get Touch Info - reports incorrect Delta information??
« Reply #8 on: May 13, 2011, 09:18:14 AM »
Hi,

 Ok, don't have time to finish this for today, but try this action. It's dealing with swipe detection, and maintain a value representing the direction and another representing the animation value  ( randing from 0 to 1, proportionnal to the screen width or height depending on the swipe direction).

 Now, that I did all the ground work, I realize that an fsm would have been better, because I can't leave this action or else I loose track of the swipe, so I need to implement some cumbersome events sending to another fsm, not big deal, but did not plan on that on my allocated time...

 So, yes, int this case, an fsm  could makes more sense, because values about the swipe woul dbe maintained and I would evolved within a single fsm between states to then trigger external events as required. But I bet the next versions of playmaker will provide much better UI selectors for events and such and will make this trivial as if I was sending events to the same fsm.

I welcome comments and suggestions on this code, as there are many ways to deal with such behavior and anyway far from complete.

 -- need to expose a lot more settings to tweak the behavior without touching the code.
 -- direction changes not taken in consideration
 -- an absolute vector representing the movement would maybe be useful, or at east easier to handle by other fsm to know what to do

and this doesn't deal with the actual visuals you want to tight to the swipe event, and that is a major part of the work. dealing with knowing where you are, where to go, and all that. But that's already a different aspect of your problem

tested on the device, and it's all smooth,


Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2011. All rights reserved.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{

[ActionCategory(ActionCategory.Device)]
[Tooltip("Control and maintain infos about swipe gestures live.")]
public class SwipeLiveGestureEvent : FsmStateAction
{

[Tooltip("How far a touch has to travel to be trigger a swipe action (in pixels)")]
public FsmInt minSwipeTriggerDistance;

[Tooltip("How far a touch has to travel to be considered a valid swipe (e.g. 1 = 1 screen distance on the swipe axis)")]
public FsmFloat minTravelTriggerPercent;
private float minTravelTriggerPixels;

[Tooltip("How fast a touch has to drag to be considered a valid swipe in pixels per seconds")]
public FsmFloat minSpeedTrigger;

[Tooltip("How fast do we animate the swipe when gesture ends")]
public FsmFloat animationSpeed = 10;


[UIHint(UIHint.Variable)]
[Tooltip("Store the swipe direction: none | left | right | up | down")]
public FsmString swipeDirection;

[UIHint(UIHint.Variable)]
[Tooltip("Store the swipe value ranging from 0 to 1")]
public FsmFloat swipeValue;


private bool touchStarted;// has a one-finger-only touch started

private bool swipeStarted; // has the gesture been accepted as a swipe.

private bool swipeCanTrigger; // the swipe gesture is now effective. If true, when gestures end, the swipe will automatically finish


private Vector2 touchStartPos;
private Vector2 swipeDrag;
private enum Direction {none,left,right,up,down};

private Direction _swipeDirection = Direction.none;


private Touch _touch_;


private float animeTarget;
private bool isAnimating;

//float touchStartTime;
public override void Reset()
{
minSwipeTriggerDistance = 2;
minTravelTriggerPercent = 0.5f; // half the screen width or height depending on the swipe direction.
minSpeedTrigger = 100;// in pixels per seconds.

_swipeDirection = Direction.none;

swipeValue = null;
swipeDirection = null;

resetSwipeData();

}

public override void OnEnter()
{
resetSwipeData();
}

public override void OnUpdate()
{

if (isAnimating){
updateTransitionAnimation();
}


// we only deal with one finger touch
if (Input.touchCount != 1)
{
return;
}

_touch_ = Input.touches[0];

switch (_touch_.phase)
{
case TouchPhase.Began:
touchStarted = true;
touchStartPos = _touch_.position;

resetSwipeData();


//touchStartTime = Time.realtimeSinceStartup;

break;

case TouchPhase.Ended:
case TouchPhase.Canceled:

if (touchStarted)
{
// check velocity trigger is distance trigger did not raise
if (!swipeCanTrigger){
float _dragReleaseDeltaMagnitude = _touch_.deltaPosition.magnitude ;
float _dragReleaseDeltaTime = _touch_.deltaTime ;
float _dragReleasespeed = _dragReleaseDeltaMagnitude*_dragReleaseDeltaTime;
Debug.Log("The user swipe released at speed"+_dragReleasespeed);

if (_dragReleasespeed>minSpeedTrigger.Value){
Debug.Log("we accept the swipe speed wise");
swipeCanTrigger= true;
}
}

triggerTransitionAnimation();
touchStarted = false;
}

break;

case TouchPhase.Moved:

// compute the drag vector
swipeDrag =  _touch_.position - touchStartPos ;

// detect when the gesture is considered a swipe
if (!swipeStarted){
// check the direction and validate the minimal distance to initiate ( not necessarly validate) a swipe gesture
if ( Mathf.Abs(swipeDrag.x) > Mathf.Abs(swipeDrag.y) && Mathf.Abs(swipeDrag.x) >= minSwipeTriggerDistance.Value  ){

swipeStarted = true;

// we go horizontaly, yes, but in what direction
_swipeDirection = swipeDrag.x<0 ? Direction.right:Direction.left;

swipeDirection.Value = _swipeDirection.ToString();

minTravelTriggerPixels = Screen.width*minTravelTriggerPercent.Value;

}else if ( Mathf.Abs(swipeDrag.x) < Mathf.Abs(swipeDrag.y) && Mathf.Abs(swipeDrag.y)>=minSwipeTriggerDistance.Value ){
swipeStarted = true;

// we go verticaly, yes, but in what direction
_swipeDirection = swipeDrag.y<0 ? Direction.up:Direction.down;

swipeDirection.Value = _swipeDirection.ToString();

minTravelTriggerPixels = Screen.height*minTravelTriggerPercent.Value;

}
}


// !swipeStarted and swipeStart check are not tight in with an "else" so that the swipeValue is straight away computed and avoid latency.
if (swipeStarted){

// let's update the swipe value
if (_swipeDirection == Direction.right || _swipeDirection == Direction.left){
swipeValue.Value = Mathf.Abs(swipeDrag.x)/Screen.width;
if (!swipeCanTrigger){
if ( Mathf.Abs(swipeDrag.x) > minTravelTriggerPixels  ){
swipeCanTrigger = true;
}
}

}else if ( _swipeDirection == Direction.up || _swipeDirection == Direction.down) {
swipeValue.Value = Mathf.Abs(swipeDrag.y)/Screen.height;
if (!swipeCanTrigger){
if ( Mathf.Abs(swipeDrag.y) > minTravelTriggerPixels  ){
swipeCanTrigger = true;
}
}

}

// also we check user input for clues like drag distance
// and decide on the gesture validity.

}

break;
}
}




private void triggerTransitionAnimation(){
if (swipeCanTrigger){
animeTarget = 1f;
isAnimating = true;

}else{
// we animate back
animeTarget = 0f;
isAnimating = true;
}
}// animateTransition



private void updateTransitionAnimation(){


// TODO: make it with iTween or EZGUI tweening system for more flexibilities.
swipeValue.Value = Mathf.Lerp(swipeValue.Value,animeTarget,animationSpeed.Value*Time.deltaTime);

// check if we have finished our animation
// check can be improved, but will do for now
if ( Mathf.Abs(swipeValue.Value-animeTarget)<0.001  ){
swipeValue.Value = animeTarget;

// WE ARE DONE WITH MOVING
isAnimating = false;
_swipeDirection = Direction.none;

resetSwipeData();

}// we have finished animating
}// _updateTransitionAnimation

private void resetSwipeData(){

if (swipeDirection != null){
swipeDirection.Value = _swipeDirection.ToString();
}

swipeCanTrigger = false;
swipeStarted = false;
swipeDrag = Vector2.zero;
if (swipeValue != null){
swipeValue.Value = 0f;
}

}


/*
void TestForSwipeGesture(Touch touch)
{
// test min distance

var lastPos = touch.position;
var distance = Vector2.Distance(lastPos, touchStartPos);

if (distance > minSwipeDistancePixels)
{
float dy = lastPos.y - touchStartPos.y;
float dx = lastPos.x - touchStartPos.x;

float angle = Mathf.Rad2Deg * Mathf.Atan2(dx, dy);

angle = (360 + angle - 45) % 360;

Debug.Log (angle);

if (angle < 90)
{
Fsm.Event(swipeRightEvent);
}
else if (angle < 180)
{
Fsm.Event(swipeDownEvent);
}
else if (angle < 270)
{
Fsm.Event(swipeLeftEvent);
}
else
{
Fsm.Event(swipeUpEvent);
}
}
}
*/
}
}



 Bye,

 Jean

IPete2

  • Playmaker Newbie
  • *
  • Posts: 23
Re: Get Touch Info - reports incorrect Delta information??
« Reply #9 on: May 13, 2011, 12:39:53 PM »
Wow - again - thanks for looking at this,

I will try it this weekend with the devices I have at home, what a great starting place for us all - thank you!

IPete2.