How to move a ball with finger gesture?
Hi, I want to move my rigidbody ball with finger gesture like the Soccer Kicks android game. I have use swipe detection and add relative force to the ball but the movement is not perfect like the Soccer Kicks game. Can anybody tell me how can I record my finger movement and move the ball according to that movement?
using UnityEngine;
using System.Collections;
public class SwipeBallControl : MonoBehaviour {
public enum Swipe { Up, Down, Left, Right, None, UpLeft, UpRight, DownLeft, DownRight };
public float minSwipeLength = 200f;
Vector2 firstPressPos;
Vector2 midPressPos;
Vector2 secondPressPos;
Vector2 currentSwipe;
public float tweakFactor = 0.5f;
public static Swipe swipeDirection;
private float startTime;
private Vector3 startPos;
private Vector3 midPos;
private Vector3 endPos;
private GameObject trail;
ArrayList allAngles;
Vector3 forceFinal = new Vector3();
float speedFinal = 0;
float eventTime = 0;
float midAngle =0;
float finalAngle =0;
bool swingActivate;
private Vector3 force;// =0;
private float speed; //=0;
void Start()
{
//initialFootballPos = transform.position;
rigidbody.velocity = Vector3.zero;
allAngles = new ArrayList();
swingActivate = false;
force = Vector3.zero;
speed = 0;
}
float swingFactor = 100;
float swingDuration = 1f;
void Update ()
{
if(swingActivate)
{
if (finalAngle < 0)
{
if (midAngle > 0)
{
if (Time.time - eventTime < swingDuration)// 1 should be replaced
{
rigidbody.AddRelativeForce(-swingFactor, 0, 0); // 10 shou
}
}
if (Mathf.Abs(midAngle) - Mathf.Abs(finalAngle) > 10)
{
if (Time.time - eventTime < swingDuration)
{
rigidbody.AddRelativeForce(-swingFactor, 0, 0);
}
}
else if (Mathf.Abs(finalAngle) - Mathf.Abs(midAngle) >10)
{
if (Time.time - eventTime <swingDuration)
{
rigidbody.AddRelativeForce(swingFactor, 0, 0);
}
}
}
else if (finalAngle >= 0)
{
if (midAngle < 0)
{
if (Time.time - eventTime < swingDuration)
{
rigidbody.AddRelativeForce(swingFactor, 0, 0);
}
}
else if (finalAngle - midAngle > 10)
{
if (Time.time - eventTime < swingDuration)
{
rigidbody.AddRelativeForce(-swingFactor, 0, 0);
}
}
else if (midAngle - finalAngle > 10)
{
if (Time.time - eventTime < swingDuration)
{
rigidbody.AddRelativeForce(swingFactor, 0, 0);
}
}
}
}
}
public void DetectSwipe ()
{
if (Input.touches.Length > 0) {
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Began && trail == null) {
startTime = Time.time;
firstPressPos = new Vector2(t.position.x, t.position.y);
startPos.x = firstPressPos.x;
startPos.y = firstPressPos.y;
startPos.z = transform.position.z - Camera.main.transform.position.z;
startPos = Camera.main.ScreenToWorldPoint(startPos);
trail = Instantiate( Resources.Load("DottedContinuousTrail"),startPos,Quaternion.identity) as GameObject;
}
if (t.phase == TouchPhase.Moved) {
if (trail!=null){
midPressPos = new Vector2(t.position.x, t.position.y);
midPos.x = midPressPos.x;
midPos.y = midPressPos.y;
midPos.z = transform.position.z - Camera.main.transform.position.z;
midPos = Camera.main.ScreenToWorldPoint(midPos);
trail.transform.position = midPos;
Vector2 delta = midPos - startPos;
float angle = Mathf.Atan(delta.y / delta.x) * (180.0f / Mathf.PI);
allAngles.Add(angle);
}
}
if (t.phase == TouchPhase.Ended) {
if (trail!=null) {
Destroy(trail);
secondPressPos = new Vector2(t.position.x, t.position.y);
endPos.x = secondPressPos.x;
endPos.y = secondPressPos.y;
endPos.z = transform.position.z - Camera.main.transform.position.z;
endPos = Camera.main.ScreenToWorldPoint(endPos);
Vector2 delta = endPos - startPos;
float distance = Mathf.Sqrt(Mathf.Pow(delta.x, 2) + Mathf.Pow (delta.y, 2));
float angle = Mathf.Atan (delta.y/delta.x) * (180.0f/Mathf.PI);
float duration = Time.time - startTime;
speed = distance/duration;
force = endPos - startPos;
force.z = force.magnitude;
force /= (Time.time - startTime);
// putting the addforce code in the end. Before that declare a bool to determin valid swipe direction
bool valid = false;
//secondPressPos = new Vector2(t.position.x, t.position.y);
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
// Make sure it was a legit swipe, not a tap
if (currentSwipe.magnitude < minSwipeLength) {
//debugInfo.text = "Tapped";
swipeDirection = Swipe.None;
return;
}
currentSwipe.Normalize();
//debugInfo.text = currentSwipe.x.ToString() + " " + currentSwipe.y.ToString();
// Swipe up
if (currentSwipe.y > 0 && currentSwipe.x > 0 - tweakFactor && currentSwipe.x < tweakFactor) {
swipeDirection = Swipe.Up;
//debugInfo.text = "Up swipe";
valid = true;
//swingActivate = false;
up = true;
// Swipe down
} else if (currentSwipe.y < 0 && currentSwipe.x > 0 - tweakFactor && currentSwipe.x < tweakFactor) {
swipeDirection = Swipe.Down;
//debugInfo.text = "Down swipe";
// Swipe left
} else if (currentSwipe.x < 0 && currentSwipe.y > 0 - tweakFactor && currentSwipe.y < tweakFactor) {
swipeDirection = Swipe.Left;
//debugInfo.text = "Left swipe";
// Swipe right
} else if (currentSwipe.x > 0 && currentSwipe.y > 0 - tweakFactor && currentSwipe.y < tweakFactor) {
swipeDirection = Swipe.Right;
//debugInfo.text = "Right swipe";
// Swipe up left
} else if (currentSwipe.y > 0 && currentSwipe.x < 0 ) {
swipeDirection = Swipe.UpLeft;
//debugInfo.text = "Up Left swipe";
valid = true;
//swingActivate = true;
upLeft = true;
// Swipe up right
} else if (currentSwipe.y > 0 && currentSwipe.x > 0 ) {
swipeDirection = Swipe.UpRight;
//debugInfo.text = "Up Right swipe";
valid = true;
//swingActivate = true;
upRight = true;
// Swipe down left
} else if (currentSwipe.y < 0 && currentSwipe.x < 0 ) {
swipeDirection = Swipe.DownLeft;
//debugInfo.text = "Down Left swipe";
// Swipe down right
} else if (currentSwipe.y < 0 && currentSwipe.x > 0 ) {
swipeDirection = Swipe.DownRight;
//debugInfo.text = "Down Right swipe";
}
if(valid)
{
eventTime = Time.time;
forceFinal = force * 1.5f;
speedFinal = speed;
midAngle = (float)allAngles[allAngles.Count / 2];
finalAngle = (float)allAngles[allAngles.Count - 1];
ShootBall();
}
}
}
} else {
swipeDirection = Swipe.None;
//debugInfo.text = "No swipe"; // if you display this, you will lose the debug text when you stop swiping
}
}
public void ShootBall()
{
ballLeftCount--;
///rigidbody.AddRelativeForce(force * 1.2f * speed, ForceMode.Impulse);
//Debug.Log("BForce: " + force + " BSpeed: " + speed);
if (speed >= 3f) {
if(speed >= 6) {
speed = 3.6f;
}
else
{
speed = speed * 0.6f;
}
}
else if (speed <= 2f) {
speed = speed / 0.4f;
}
if(force.z >= 5f)
force.z = 5f;
if(force.y >= 3f)
force.y = 3f;
//Debug.Log("AForce: " + force + " ASpeed: " + speed);
//Vector3 force2 = new Vector3(2f, 2.5f, 3.3f);
//rigidbody.AddRelativeForce(force2 * 3.6f, ForceMode.Impulse);
rigidbody.AddRelativeForce(force * speed, ForceMode.Impulse);
ballKicked = true;
StartCoroutine("ReturnBall");
}
IEnumerator ReturnBall() {
///rigidbody.constraints = RigidbodyConstraints.FreezeAll;
yield return new WaitForSeconds(4.0f);
// rigidbody.velocity = Vector3.zero;
// rigidbody.constraints = RigidbodyConstraints.None;
// transform.position = initialFootballPos;//Vector3.zero;
if (ballLeftCount == 0) {
ballLeftCount = 5;
//Menu Load
if(TriggeringGoal.score > PlayerPrefs.GetInt("Player Score")) {
PlayerPrefs.SetInt("Player Score", TriggeringGoal.score);
}
//Menu Load
TriggeringGoal.score = 0;
Application.LoadLevel(0);
}
else {
Application.LoadLevel ("Shoot & Win");
}
}
}
Hey @reshad did u implemented this logic of moving ball on swipe
Answer by Owen-Reynolds · May 25, 2014 at 05:19 PM
Getting just the right feel is a lot of little tweaks. You can play with the ball's physics settings. And notice how the code has adjustable minSwipeLen
and tweakFactor.
Also, see all those numbers in the code: 3, 3.6, force*1.5 ... all can be adjusted (if you know what they do.)
For a soccer ball, you may want to check where on the ball they hit (raycast?,) and give the ball a spin/curve in the other direction. That would be a whole new and different chunk of code. But, if you aren't a programmer, changing the program will probably just make things worse.
For me, getting a swipe from "works OK" to "very good" takes more time than making it work OK, and I have to try a lot of things that don't work.
$$anonymous$$y swipe has already worked. In that process I can only flick the ball with no curve. I can add additional force to the rigidbody into left or right direction but not perfect with the finger gesture like Soccer $$anonymous$$icks game. So I want a complete solution about how the Soccer $$anonymous$$icks have done the ball shoot?
Answer by Shifty-Geezer · Jul 23, 2017 at 08:23 PM
When I created a prototype for my football game, it was working within 3 hours. To get the finished product took over 6 months including two months working on perfecting the controls and the kicking. Someone asking me to just hand over all that work would be kinda offensive, truth be told. Unity Answers is here to tell you how to solve specific problems, and you get free advice and support for that. It's not here to write your game for you and give you perfect code you can drop into your game. Development is hard, creating perfect gameplay is hard, and you need to be patient and persistent and willing to do the hard graft. As Owen-Reynolds says, you have to play with the parameters, understand how they all work, and come up with your own solution.
If you have the mechanics of touch input kicking the ball working, the rest is up to you. If you have a specific query like how to add read gestures or how to add forces to a RB, feel free to ask.
Your answer
Follow this Question
Related Questions
Need some Help with Swipes! 0 Answers
Some things wrong with swipe move! 0 Answers
Sprite occasionally moving to left when dragging to right 0 Answers
Detect a swipe gesture over a Raycast 0 Answers
Touch based rotation of 3d model 0 Answers