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 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(Input.mousePosition) - Camera.main.ScreenToWorldPoint(prevMousePosition);
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;
}
}
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, Guys!
Check my asset called Throw Control.
There is “Flick Mode”.