- Home /
touch.position, Mathf.Abs... Please Help Me!!
Hello,
I'm very new to this. I don't know much about scripting, but I'm starting to wrap my head around it.
I'm having trouble with detecting a swipe. I'm not getting errors in my script, but it doesn't seem to be calculating Mathf.Abs properly and therefore I'm not achieving the desired effect.
I narrowed it down and I believe that it is a problem with what touch.position is returning. This is what I'm doing:
If I want to get a vertical swipe I get the start touch.position and end touch.position and subtract the end position ( x ) from the start position ( x ) and see if it is less than a specific pixel value (200 pixels for example). If it is less than the pixel value, then it is considered to be a swipe. I do the same for horizontal swipes. (there are other conditions that have to be met in order for a swipe to be recognized, but this is the only problematic condition)
The problem is that the end touch.position is always returning a larger number for x than for y regardless of wether it is a vertical or horizontal swipe. My understanding is that touch.position returns the Vector 2 like this (x,y).
Is there anybody out there that can help??? Please provide an example for the ultra newb.
Here is my code:
#pragma strict
function Start () {
}
var touchedObj: boolean = false; // Has the object been touched
var moving: boolean = false; // this has to be true to move
var comfortZoneVerticalSwipe: float = 500; // the vertical swipe will have to be inside a 50 pixels horizontal boundary
var comfortZoneHorizontalSwipe: float = 50; // the horizontal swipe will have to be inside a 50 pixels vertical boundary
var minSwipeDistance: float = 14; // the swipe distance will have to be longer than this for it to be considered a swipe
var maxSwipeTime: float = 10; // the swipe time will have to be less than this to be considered a swipe
//the following 4 variables are used in some cases that I don’t want my character to be allowed to move on the board (it’s a board game)
var allowGoUp: boolean = true;
var allowGoRight: boolean = true;
var allowGoLeft: boolean = true;
var allowGoDown: boolean = true;
function Update ()
{
if (Input.touchCount >0)
{
var touch = Input.touches[0];
switch (touch.phase)
{ //following are 2 cases
case TouchPhase.Began: //here begins the 1st case
print("began");
var ray = Camera.main.ScreenPointToRay(touch.position);
var hit : RaycastHit;
var layerMask = 1 << 8;
var startPos = touch.position;
var startTime = Time.time;
if (Physics.Raycast (ray, hit, Mathf.Infinity, layerMask))
{
print("touched");
touchedObj = true;
}
break; //here ends the 1st case
case TouchPhase.Ended: //here begins the 2nd case
print("end");
Debug.Log (startPos);
var swipeTime = Time.time - startTime;
var swipeDist = (touch.position - startPos).magnitude;
var endPos = touch.position;
Debug.Log (endPos); //This is how I found that the x value in the end touch.position is always greater regardless of the horizontal or vertical swipe
if (touchedObj && Mathf.Abs(touch.position.x - startPos.x)<comfortZoneVerticalSwipe && (swipeTime < maxSwipeTime) && (swipeDist > minSwipeDistance) && Mathf.Sign(touch.position.y - startPos.y)>0 && !moving && allowGoUp)
{
//... then go up
moving=true;
print ("UPUPUP");
// code here for upward movement
}
if (touchedObj && (Mathf.Abs(touch.position.x - startPos.x))<comfortZoneVerticalSwipe && (swipeTime < maxSwipeTime) && (swipeDist > minSwipeDistance) && Mathf.Sign(touch.position.y - startPos.y)<0 && !moving && allowGoDown)
{
//... then go down
moving=true;
print ("DOWNDOWN");
// code here for downward movement
}
if (touchedObj && (Mathf.Abs(touch.position.y - startPos.y))<comfortZoneHorizontalSwipe && (swipeTime < maxSwipeTime) && (swipeDist > minSwipeDistance) && Mathf.Sign(touch.position.x - startPos.x)<0 && !moving && allowGoLeft)
{
//... then go left
moving=true;
print ("LEFTLEFT");
// code here for left movement
}
if (touchedObj && (Mathf.Abs(touch.position.y - startPos.y))<comfortZoneHorizontalSwipe && (swipeTime < maxSwipeTime) && (swipeDist > minSwipeDistance) && Mathf.Sign(touch.position.x - startPos.x)>0 && !moving && allowGoRight)
{
//...then go right
moving=true;
print ("RIGHTRIGHT");
// code here for right movement
}
break; //here ends the 2nd case
}
}
}
Keep in mind that I'm using "Unity Remote 3" to test this on my iPad.
I was thinking that a raycast might work, but I would think that it isn't necessary since touch.position should do the job fine. If you think a raycast is the only way to do this, could you please supply an example.
Thanks a mil in advance.
Hi mate!
I strongly recommend to use Touch$$anonymous$$it by Prime31. It is free.
It make a lot easier to implement touch gesture and events.
http://www.youtube.com/watch?v=s7bjH07p-04 https://github.com/prime31/Touch$$anonymous$$it
I used to program the gesture by myself but the i moved to Touch$$anonymous$$it. You can even program specific gestures based on the core of the kit.
Hey, I'll take a look.
Thanks for that. Still hoping somebody can answer my question though.
You have to download the github project and move the files and folders to the proper ones inside your unity project. You can remove the .meta files which are not necessary for you. You need all those files. I basically remember that you have to put the folder inside the "Assets" folder into your "Assets" folder.
Then checkout the github instructions, which mention as follows: "If you are just using the built in recognizers, check out the demo scene which shows how to use them. You will want to use Unity's script execution order (Edit -> Project Settings -> Script Execution Order) to ensure that Touch$$anonymous$$it executes before your other scripts. This is just to ensure you have your input when the Update method on your listening objects runs. If you want to make your own (and feel free to send pull requests if you make any generic recognizers!) all you have to do is subclass T$$anonymous$$AbstractGestureRecognizer and implement the three methods: touchesBegan, touches$$anonymous$$oved and touchesEnded. Recognizers can be discrete (they only complete once like a tap or long touch) or continous (they can fire continuously like a pan). Recognizers use the state veriable to deter$$anonymous$$e if they are still active, completed or failed. If you set the state to Recognized, the completion event is fired automatically for you and the recognizer is reset in preparation for the next set of touches."
I strongly recommend first checking the videos and the start playing around with the demo/example scenes to understand how to incorporated in your project.
Answer by robertbu · Feb 03, 2013 at 09:55 PM
I took a look at your code above on the iPad (i.e. not using Unity Remote). There are a few problems. The one that is likely causing you issues is that 'startPos' is a local variable to Update(), so it loses it value between the time Update is call for your TouchPhase.Began case and for the TouchPhase.Ended case. You need to move it out of the Update() function.
More minor issues are that touchedObj is never reset to false, so after a first swipe on the object, all other swipes will be passed on even if the swipe does not touch the object. Another small issue is that you are using screen/pixel calculations for some of your checks (how big (i.e. as a percentage of the screen) the swipe is will heavily depend on the resolution of the device).
On the actual device the pixel coordinates returned by touch.position were correct...the x value wasn't always larger than the y value, and the values seem correct with respect to the coordinates of the screen (i.e. 0,0 in the upper left corner).
I second @VicM 's suggestion to take a look at something to abstract away touch code. We use FingerGestures.
Thanks!!! Coding is making me feel like I'm partially retarded because I've never done it before, but I'm enjoying the climb regardless of how many times I fall.
Looking forward to using Touch$$anonymous$$it.. Thanks again!!
Your answer
Follow this Question
Related Questions
Camera momentum after lifting finger 0 Answers
Android "mouse" speed while GetMouseButtonDown(0) 0 Answers
Get touch position? 0 Answers
Reproducing the "spin" effect of Flick Kick Football 1 Answer
Detect swipe up gesture IOS 1 Answer