- Home /
constrain 2d gameobject to finger position (js)
hello,i am new to unity and i have been relentlessly trying to accomplish this with no success. what i would like to do is this - have an empty gameobject in the scene which is not active, but when the user starts the swipe the gameobject becomes active and automatically snaps to the position of the finger on the screen, and is then constrained to the position of the finger on the screen and follows the swipe regardless of the speed of the swipe or direction. what i have tried so far is this - instantiate gameobject when the touchphase.moved is started, destroy the gameobject on touchphase.ended, and attach the following script to the prefab:
var speed : float = 0.1;
function Update () {
if (Input.touchCount > 0 &&
Input.GetTouch(0).phase == TouchPhase.Moved) {
var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;
transform.Translate (touchDeltaPosition.x * speed,
touchDeltaPosition.y * speed, 0);
}
}
but this did not work, what happened is that prefabs were continuously instantiated as long as the touchphase.moved was happening,i only wanted one spawned per swipe motion. additionally the prefab was being spawned at 0,0,0, and not at the touch point (probably a problem with the spawn script).
so then i thought that i could have the gameobject in the scene, and then automatically snap/start at/ move to the position of the finger when the swipe begins. but i am not sure how to get this done. i am using a trail renderer to see where the gameobject is moved during the swipe. i am also using JavaScript. any help with this will certainly be greatly appreciated, i have been trying a variety of different methods, but nothing seems to work, also if someone could point out a better method with scripting i would love to learn from it. thank you in advance.
Answer by robertbu · Mar 27, 2014 at 05:13 AM
You need to use the Touch.position, not the Touch.deltaPosition, and that position must be converted from a screen position to a world position. Here is a bit of example code (using the mouse). To test:
Start a new scene in the editor
Attach the following script to an empty game object
Create a prefab
Select the empty game object with the script, and drag the prefab to the 'prefab' variable on the script.
The 'dist' parameter is the distance in front of the camera to place objects. You may want to set this value.
pragma strict
var prefab : Transform; var dist : float = 10.0; var curr : Transform;
function Update() { if (Input.GetMouseButtonDown(0)) { var pos = Input.mousePosition; pos.z = dist; pos = Camera.main.ScreenToWorldPoint(pos); curr = Instantiate(prefab, pos, Quaternion.identity); } if (Input.GetMouseButton(0)) { pos = Input.mousePosition; pos.z = dist; curr.position = Camera.main.ScreenToWorldPoint(pos); } }
You'll have to convert the code to touch, but the core of the change is just replacing 'Input.mousePosition' with the Touch.position of the touch you are using.
Hello, thanks so much for the response. It works well, but I'm having difficulty converting it to touch. I changed the input. $$anonymous$$ousePosition to gettouch(0).position.... But that didn't work.... I'm quite sure I'm doing something wrong. I'm sorry but I'm still new.
#pragma strict
var prefab : Transform;
var dist : float = 10.0;
var curr : Transform;
function Update() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) {
var pos = Input.GetTouch(0).position;
pos.z = dist;
pos = Camera.main.ScreenToWorldPoint(pos);
curr = Instantiate(prefab, pos, Quaternion.identity);
}
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.$$anonymous$$oved) {
pos = Input.GetTouch(0).position;
pos.z = dist;
curr.position = Camera.main.ScreenToWorldPoint(pos);
}
}
i tried this, because i assumed that the touchphase.began reads the first touch like getmousebuttondown, and then i assumed that touchphase.moved would read the finger swipe or movement on the screen, like getmousebutton(0). however i get an error in the console that .z is not a member of vector2, did i mean .x, for var pos.z . i changed it to .x, but that didn't resolve the issue and i'm not getting the touch conversion.
another question please, something i noticed - i have other instantiated objects in the scene that i touch to destroy with the following script - var pop : GameObject; var ball : GameObject;
function Update ()
{
if (Input.Get$$anonymous$$ouseButtonDown(0))
{
var hitm : RaycastHit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hitm.collider != null && hitm.collider.gameObject == ball)
{
score.gameScore += 10;
Instantiate(pop, hitm.point, Quaternion.identity);
Destroy (hitm.collider.gameObject);
}
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began){
if(hitm.collider != null && hitm.collider.gameObject == ball)
{
score.gameScore += 10;
Instantiate(pop, hitm.point, Quaternion.identity);
Destroy (hitm.collider.gameObject);
}
}
}
}
but when i added the script to the scene, this script stops working and the balls do not get destroyed when i touch them. i'm not sure why..... again thanks so much for all of your help i'm learning as i go along.
The main issue with your finger drag code is in this line:
var pos = Input.GetTouch(0).position;
In Javascript, when a variable is assigned like this, it gets its type from what is assigned. Input.mousePosition is a vector3. Touch.position is a Vector2 (and therefore does not have a 'z' component). Javascript allows you to convert between types, so the fix is to explicitly declare the type. Change the line to:
var pos : Vector3 = Input.GetTouch(0).position;
There is another issue in your code. If the user puts down one finger, you get an instantiate. Then if the user puts down a second finger you will get a second object that will track the first finger's position. A fix for this would be changing line 8 to:
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
As for your additional issue, please open a new question. We try each UA question focused on a single specific issue. Lots of people search UA for answers, and it works better if the questions are focused on a single issue.
Your answer
Follow this Question
Related Questions
TouchPhase doesn't end when player swipes off screen 1 Answer
Deactivate Swipe Controls on Pause? 0 Answers
Tap for variable height jump, swipe to dash 1 Answer
Move gameObject with swipe in 3d space ? 1 Answer
How to move player once per swipe 2 Answers