- Home /
Smooth movement using transform.Translate
I am making a 2.5d game with three "paths" lined up along the z axis, the player is moving forward along the x axis, i am trying to make it so that when you swipe up on the screen it moves "25.0f" on the z axis and when you swipe down it does the same downwards. This is the code i am using:
public float moveCar = 25.0f;
//First establish some variables
private Vector3 fp; //First finger position
private Vector3 lp; //Last finger position
public float dragDistance; //Distance needed for a swipe to register
// Update is called once per frame
void Update()
{
//Examine the touch inputs
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fp = touch.position;
lp = touch.position;
}
if (touch.phase == TouchPhase.Moved)
{
lp = touch.position;
}
if (touch.phase == TouchPhase.Ended)
{
//First check if it's actually a drag
if (Mathf.Abs(lp.x - fp.x) > dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{ //It's a drag
//Now check what direction the drag was
//First check which axis
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{ //If the horizontal movement is greater than the vertical movement...
if (lp.x>fp.x) //If the movement was to the right
{ //Right move
//MOVE RIGHT CODE HERE
}
else
{ //Left move
//MOVE LEFT CODE HERE
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y>fp.y) //If the movement was up
{ //Up move
transform.Translate (Vector3.right * moveCar);
}
else
{ //Down move
transform.Translate (Vector3.left * moveCar);
}
}
}
else
{ //It's a tap
//TAP CODE HERE
transform.Translate (Vector3.up * 6);
}
This does what i want, except that the movement isn't smooth at all, it just kind of teleports to the new location, i was wondering how i could make it move to the new position smoother. I have tried looking into the Vector3.Lerp but didnt really understand how to implement it. Any tips on how i could achieve the smoother movement effect? :)
You could use Time.deltaTime, but it should be called from a loop or Update(). What you're doing now is basically moving the player to a direction by the value of 'moveCar'. What you should do is use
transform.Translate(Vector.right * moveCar * Time.deltaTime)
Perhaps you could use a bool to check if the player is supposed to be moved, and trigger a movement function from Update()?
Hey sorry for taking so long to respond! I tried with Time.deltatTime, but now ins$$anonymous$$d of moving smoother it just moves shorter distance than before :/
Answer by UziMonkey · Jan 12, 2015 at 09:45 AM
First, you'll need to store the destination location to move to over time. This is not something that can be done in a single update call, and you'll need to store the state between frames. So you can start by putting in something like this.
public Vector3 destination;
Initialize that in Start to your current location, so it doesn't try to move right away.
void Start() {
destination = transform.location;
}
And now instead of immediately translating to your destination, in your input detection code all you need to do is something like this.
destination += Vector3.left * moveCar;
You're all set up to go, now the Vector3.Lerp part. Vector3.Lerp will return a point on a line between two vectors. The "time" parameter you give it is something between 0 and 1, at 0 it'll return the first vector, at 1 it'll return the second vector, at 0.5 a point in the middle of the two vectors, etc. But you don't need to keep track of time. There's a clever way of doing this.
transform.position = Vector3.Lerp(transform.position, destination, 0.5f * Time.deltaTime);
In this code, instead of keeping track of how far we've gone and how long we have to get there, we continually pass 0.5f (multiplied by Time.deltaTime, since we're doing this every frame), so we're continually aiming for a point halfway between where the object is this frame, and where we want to go. The first frame you'll accelerate quickly. As you start to get closer, you'll continually slow down as the halfway point gets closer and closer to the destination. It's very simple, and it's certainly not the best way, but I think you'll find this script useful.
using UnityEngine;
using System.Collections;
public class SmoothMove : MonoBehaviour {
public Vector3 destination;
public float speed = 0.1f;
void Start () {
destination = transform.position;
}
void Update () {
transform.position = Vector3.Lerp(transform.position, destination, speed * Time.deltaTime);
}
}
Simply attach this to an object, set the destination Vector3 and it'll move there relatively smoothly.
Hey thanks this was helpful, but one issue is that now the player is unable to move forward on the X axis, it kind of is stuck to one position on x? :)
Hey did you find a good solution for this i have the sale exacte problem please help
Answer by spenzhg · Apr 18, 2016 at 07:14 AM
I would suggest using a coroutine instead of changing the transform through Update. Using a coroutine makes the code look nicer and there's significantly less overhead. (Read more here: Unity Docs)
Here is a generic example that moves an object smoothly in the x direction by 1 unit when someone hits the right arrow key (Attach this to what you want to move.):
using UnityEngine;
using System.Collections;
public class Move_EX : MonoBehaviour {
Vector3 right = new Vector3 (1f, 0, 0); //Vector in the direction you want to move in.
void Update () {
if (Input.GetKeyDown ("right")) {//Using update to capture the keypress.
StartCoroutine (smooth_move (right, 1f)); //Calling the coroutine.
}
}
IEnumerator smooth_move(Vector3 direction,float speed){
float startime = Time.time;
Vector3 start_pos = transform.position; //Starting position.
Vector3 end_pos = transform.position + direction; //Ending position.
while (start_pos != end_pos && ((Time.time - startime)*speed) < 1f) {
float move = Mathf.Lerp (0,1, (Time.time - startime)*speed);
transform.position += direction*move;
yield return null;
}
}
}
Thank you for this code, honestly it worked perfectly and it was what I was looking for :D
Hello Sir, This code works great for smooth movement. But object is not moving with constant speed.
Your answer
Follow this Question
Related Questions
3 coroutines to ease in lerp, MoveToward steady pace, and ease out lerp 0 Answers
Smooth touch for map 0 Answers
Collision.contacts? 1 Answer
Stop a Lerp from looping 3 Answers
How to Gradually Increase Speed with Lerp or Slerp? 1 Answer