- Home /
How to flick an object on mobile devices
I am trying to create a script that allows the user to flick a ball on mobile devices. It is a 2D game and I am using a rigidbody but I don't know how to get it so that when the user releases his/her finger from the screen the object will be going into the correct direction in which the finger flicked. I have a script that I thought would work but it just randomly spazzes out.
using UnityEngine;
using System.Collections;
public class DragScript : MonoBehaviour {
private Vector2 deltaPosition;
private bool grabbed;
// Update is called once per frame
void Update () {
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Input.GetMouseButtonDown(0) && collider2D.OverlapPoint(mousePos) && !grabbed)
{
grabbed = true;
deltaPosition = transform.position;
}
if (Input.GetMouseButton(0) && grabbed)
{
transform.position = mousePos;
}
if (Input.GetMouseButtonUp(0) && grabbed)
{
float dX = mousePos.x - deltaPosition.x;
float dY = mousePos.y - deltaPosition.y;
Vector2 newVel = new Vector2(dX, dY);
print(newVel);
rigidbody2D.velocity = newVel;
deltaPosition = Vector2.zero;
grabbed = false;
}
}
}
I didn't look at this too in depth but one thing that might be causing an issue is it looks like you are calculating a velocity with a position. Velocity should be distance divided by time. This will cause unpredictable results based on the changes in update times. Also, I would suggest getting the last few values of change and finding an average ins$$anonymous$$d of just using the last one (see my answer below).
Answer by calebheale · Jul 22, 2014 at 06:32 AM
I just built something to test this a few days ago. Its pretty rough but it might be a step in the right direction for you. You can attach this script to an object with a RigidBody2D and a BoxCollider2D (probably want a sprite renderer too so you can actually see it) and then grab and throw it around. The basic premise is that it grabs the last 5 movements of the mouse and averages their velocities with the deltaTime to get an idea of the general direction the mouse is headed. Then applies a force when the mouse is released. The part that is commented out is just something extra to keep it in the window so I could test it without them flying out of view. Feel free to ask about anything that is unclear but the code should be pretty self explanatory.
using UnityEngine;
using System.Collections;
public class Move : MonoBehaviour {
private const int VECTOR_COUNT = 5;
private int vectorIndex = 0;
private Vector3[] positionChanges;
private Vector3 prevMousePosition;
private float[] prevTimes;
private bool curDown = false;
private bool prevDown = false;
void Start() {
prevMousePosition = Vector3.zero;
positionChanges = new Vector3[VECTOR_COUNT];
prevTimes = new float[VECTOR_COUNT];
for (int i = 0; i < VECTOR_COUNT; i++) {
positionChanges [i] = Vector3.zero;
prevTimes[i] = 0;
}
}
void Update () {
if (curDown) {
// if still down just follow the mouse (finger)
Vector3 amountMoved = Camera.main.ScreenToWorldPoint (positionChanges[(vectorIndex - 1 + VECTOR_COUNT) % VECTOR_COUNT]) - Camera.main.ScreenToWorldPoint (new Vector2 (0, 0));
transform.position = transform.position + amountMoved;
} else if(prevDown) {
// just came up so calculate and set velocity
float totalTime = 0;
Vector3 totalDistance = Vector3.zero;
Vector3 velocity;
for(int i = 0; i < VECTOR_COUNT; i++) {
totalTime += prevTimes[i];
totalDistance += positionChanges[i];
}
velocity = totalDistance / totalTime;
velocity = Camera.main.ScreenToWorldPoint (velocity) - Camera.main.ScreenToWorldPoint (Vector3.zero);
rigidbody2D.velocity = velocity;
}
positionChanges [vectorIndex] = Input.mousePosition - prevMousePosition;
prevTimes [vectorIndex] = Time.deltaTime;
vectorIndex = (vectorIndex + 1) % VECTOR_COUNT;
prevDown = curDown;
prevMousePosition = Input.mousePosition;
/*
if (!curDown) {
Vector2 temp = rigidbody2D.velocity;
if((transform.position.y > Camera.main.orthographicSize && rigidbody2D.velocity.y > 0) ||
(transform.position.y < -Camera.main.orthographicSize && rigidbody2D.velocity.y < 0))
temp.y *= -1;
if((transform.position.x > Camera.main.orthographicSize * Camera.main.aspect && rigidbody2D.velocity.x > 0) ||
(transform.position.x < -Camera.main.orthographicSize * Camera.main.aspect && rigidbody2D.velocity.x < 0))
temp.x *= -1;
rigidbody2D.velocity = temp;
}
*/
}
void OnMouseDown() {
print ("down");
curDown = true;
rigidbody2D.velocity = Vector2.zero;
}
void OnMouseUp() {
print ("up");
curDown = false;
}
}
awesome. your code is working to me. is this the same to this game? http://www.youtube.com/watch?v=OZy7Vb3qpJg slide soccer. sorry i'm new developer in unity. thx man
Answer by perrygarg · Jul 22, 2014 at 06:33 AM
this is code for detecting swipes on mobile devices, just copy paste it to your script and write what you want to do in four functions at end of script. It will work in exact way you want. You write code only for Up,Down,Right and Left but it will work for flick in every direction because update is being called every frame at fast rate.
using UnityEngine;
using System.Collections;
public class swipeDetect : MonoBehaviour {
public float minDisSwipeX,minDisSwipeY;
private Vector2 startPos;
void Update () {
if (Input.GetKeyDown(KeyCode.Escape)) {
Application.Quit();
}
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer) {
if(Input.touchCount>0)
{
Touch tch = Input.GetTouch(0);
switch(tch.phase)
{
case TouchPhase.Began:
startPos = tch.position;
break;
case TouchPhase.Ended:
float swipeVer = (new Vector2(0,tch.position.y)-new Vector2(0,startPos.y)).magnitude;
if(swipeVer >= minDisSwipeY)
{
float signSwipe = Mathf.Sign(tch.position.y - startPos.y);
if(signSwipe > 0)
{
//up
Up();
}
else if(signSwipe < 0)
{
//down
Down();
}
}
float swipeHor = (new Vector2(tch.position.x,0)-new Vector2(startPos.x,0)).magnitude;
if(swipeHor >= minDisSwipeX)
{
float signSwipe = Mathf.Sign(tch.position.x - startPos.x);
if(signSwipe > 0)
{
//right
Right();
}
else if(signSwipe < 0)
{
//left
Left();
}
}
break;
}
}
}
}
void Up()
{
Debug.Log("Up Swiped");
//write your code here for up flick
}
void Down()
{
Debug.Log("Down Swiped");
//write your code here for up flick
}
void Right()
{
Debug.Log("Right Swiped");
//write your code here for right flick
}
void Left()
{
Debug.Log("Left Swiped");
//write your code here for left flick
}
}
hey man. please give us an example for that code in debug.log. thanks I'm new in unity. thanks
Answer by makaka-org · Jun 19, 2018 at 12:21 PM
Hey, Guys!
Check my asset called Throw Control.
There is "Flick Mode".
Your answer
Follow this Question
Related Questions
Drag around riggidbodies with a "pin" 0 Answers
Moving object with tilting the device. 1 Answer
Drag object relative to camera 1 Answer
How to rotate an object using touch controls 3 Answers
Realistic methods of propulsion without friction involved 0 Answers