Okay so i currently have a 2d square, every time you tap it adds force so the player can go upwards. I also have three empty game objects that are parented to said square that uses these empty game objects as lanes. when you swipe left, you transition to the left object, and when you swipe right you transition to the right object. however you can do this infinitely and the transition isnt a smooth transition. Here is the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Swipe : MonoBehaviour {
public int laneInt = 0;
public GameObject laneZero;
public GameObject laneNegitiveOne;
public GameObject lanePositiveOne;
public bool transformLock = false;
public bool rightWall;
public bool leftWall;
public float upForce = 300f;
private Vector3 fp;
private Vector3 lp;
private float dragDistance = 0.25f;
private Rigidbody2D rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
GetTap();
PCInput();
LaneCheck();
SwipeCalc();
}
void SwipeCalc()
{
if (Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
fp = touch.position;
lp = touch.position;
}
else if (touch.phase == TouchPhase.Moved)
{
lp = touch.position;
}
else if (touch.phase == TouchPhase.Ended)
{
lp = touch.position;
if (Mathf.Abs(lp.x - fp.x) > dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
if ((lp.x > fp.x))
{
Debug.Log("Right Swipe");
laneInt++;
transformLock = true;
}
else
{
Debug.Log("Left Swipe");
laneInt--;
transformLock = true;
}
}
else
{
if (lp.y > fp.y)
{
Debug.Log("Up Swipe");
}
else
{
Debug.Log("Down Swipe");
}
}
}
else
{
Debug.Log("Tap");
}
}
}
}
void PCInput()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.velocity = Vector2.zero;
rb.AddForce(new Vector2(0, upForce));
transformLock = false;
}
if (Input.GetKeyDown(KeyCode.D))
{
laneInt++;
transformLock = true;
}
if (Input.GetKeyDown(KeyCode.A))
{
laneInt--;
transformLock = true;
}
}
void LaneCheck()
{
if (laneInt >= 1)
{
laneInt = 1;
}
if (laneInt <= -1)
{
laneInt = -1;
}
if (laneInt == 0 && transformLock == true)
{
transform.position = laneZero.transform.position;
transformLock = false;
}
if (laneInt == 1 && transformLock == true)
{
transform.position = lanePositiveOne.transform.position;
transformLock = false;
}
if (laneInt == -1 && transformLock == true)
{
transform.position = laneNegitiveOne.transform.position;
transformLock = false;
}
}
void GetTap()
{
for (int i = 0; i < Input.touchCount; ++i)
{
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
rb.velocity = Vector2.zero;
rb.AddForce(new Vector2(0, upForce));
}
}
}
}
You’re tightly coupling laneInt with your transform position. So, as soon as laneInt changes, you’re immediately changing the position of your object. Instead, I would treat laneInt as a “desired” indicator. So, whatever value is in laneInt indicates where you ultimately want the car to be. However, it doesn’t necessarily mean the car is there. But the car should always be on its way there.
You can accomplish this without a lot of changes in your code. I’d remove "transformLock " entirely. I don’t think you need it. Then, instead of immediately setting transform.position, you gradually move it. So, instead of…
transform.position = laneZero.transform.position;
…try something like this…
if (Vector3.Distance(transform.position, laneZero.transform.position) > 0.001f) {
transform.position = Mathf.Lerp(transform.position, laneZero.transform.position, 0.5f);
} else {
transform.position = laneZero.transform.position;
}
Play around with the position adjustment code a bit. Using Lerp with a constant like this is kind of a quick-and-dirty way to cause the object to approach the desired position over time, but there are other ways to animate the transition.
The reason you don’t need “transformLock” is because it seems reasonable for the player to swipe twice quickly, to go from the far left land to the far right lane. This animation approach will support that.
(Note: I free-handed the code, so hopefully I didn’t make any little mistakes here).
Note that Lerp with a constant will be frame-rate dependent (ie, it would switch lanes twice as fast at 60 FPS vs 30 FPS). You could use Time.deltaTime * [constant] instead, or use Vector3.MoveTowards but vary the speed based on the distance.
Okay, so after tweaking the piece of code you gave me and fixing it up a bit, I got the movement to work, except now the problem I have is, gravity isn’t effecting the square anymore. Which is why i had that bool there because i was playing with ways to have both the lane movement but the constant descending factor.
This is the current script. I was trying to make a bool to toggle after the movement had finished so that gravity can keep working with the rigid body so its not always doing a movement but that isn’t working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Swipe : MonoBehaviour {
public int laneInt = 0;
public GameObject laneZero;
public GameObject laneNegitiveOne;
public GameObject lanePositiveOne;
public float upForce = 300f;
public float transitionSpeed = 100f;
private Vector3 fp;
private Vector3 lp;
private float dragDistance = 0.5f;
private Rigidbody2D rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
GetTap();
PCInput();
LaneCheck();
SwipeCalc();
}
void SwipeCalc()
{
if (Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
fp = touch.position;
lp = touch.position;
}
else if (touch.phase == TouchPhase.Moved)
{
lp = touch.position;
}
else if (touch.phase == TouchPhase.Ended)
{
lp = touch.position;
if (Mathf.Abs(lp.x - fp.x) > dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
if ((lp.x > fp.x))
{
Debug.Log("Right Swipe");
laneInt++;
}
else
{
Debug.Log("Left Swipe");
laneInt--;
}
}
else
{
if (lp.y > fp.y)
{
Debug.Log("Up Swipe");
}
else
{
Debug.Log("Down Swipe");
}
}
}
else
{
Debug.Log("Tap");
}
}
}
}
void PCInput()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.velocity = Vector2.zero;
rb.AddForce(new Vector2(0, upForce));
}
if (Input.GetKeyDown(KeyCode.D))
{
laneInt++;
}
if (Input.GetKeyDown(KeyCode.A))
{
laneInt--;
}
}
void LaneCheck()
{
if (laneInt >= 1)
{
laneInt = 1;
}
if (laneInt <= -1)
{
laneInt = -1;
}
if (laneInt == 0)
{
if (Vector3.Distance(transform.position, laneZero.transform.position) > 0.001f)
{
transform.position = new Vector3(Mathf.Lerp(transform.position.x, laneZero.transform.position.x, transitionSpeed * Time.deltaTime), 0, 0);
}
else
{
transform.position = laneZero.transform.position;
}
}
if (laneInt == 1)
{
if (Vector3.Distance(transform.position, lanePositiveOne.transform.position) > 0.001f)
{
transform.position = new Vector3(Mathf.Lerp(transform.position.x, lanePositiveOne.transform.position.x, transitionSpeed * Time.deltaTime), 0, 0);
}
else
{
transform.position = lanePositiveOne.transform.position;
}
}
if (laneInt == -1)
{
if (Vector3.Distance(transform.position, laneNegitiveOne.transform.position) > 0.001f)
{
transform.position = new Vector3(Mathf.Lerp(transform.position.x, laneNegitiveOne.transform.position.x, transitionSpeed * Time.deltaTime), 0, 0);
}
else
{
transform.position = laneNegitiveOne.transform.position;
}
}
}
void GetTap()
{
for (int i = 0; i < Input.touchCount; ++i)
{
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
rb.velocity = Vector2.zero;
rb.AddForce(new Vector2(0, upForce));
}
}
}
}
It’s not obvious to me from this code how you’re using gravity. However, one thing I notice from your new code is that you’re setting the transform.position to a new Vector3 with Y and Z components set to 0. Previously you were setting the transforms position to the lanePositiveOne, or other lane, transform positions. Now you’re setting it to 0. I’m not sure whether that’s related, and maybe those lane position objects always have a Y and Z position of 0, but I figured I’d point it out.
If you have a rigidbody on the same object you’re setting transform.position on, you’re likely to run into some issues… I’m not certain, but changing the position might reset the physics simulation, causing it to not accumulate much (if any) velocity from gravity. That seems likely given that the new code is changing the position more frequently than your original code. If that’s what’s happening, you might be better off adding sideways force until the object is where it belongs, rather than manually setting the position. It’s probably reasonably simple to call AddForce with a specific amount to get it to move the way you want. In that case, it’s likely a single call to AddForce per swipe (though that whole approach still feels a bit off to me…)