I want to move my character smoothly whenever i pressed te arrow. I try Vector3.SmoothDamp and Vector3.Lerp but whenever I using SmoothDamp method the texture move a little bit without any effect and Lerp does not have any effect (looks the same as transform.position += Vector3.left + PLAYER_MOVE_VAL)
Code:
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
moveLeft();
if (Input.GetKeyDown(KeyCode.RightArrow))
moveRight();
foreach (Touch touch in Input.touches)
{
if (touch.position.x < Screen.width / 2)
moveLeft();
else if (touch.position.x > Screen.width / 2)
moveRight();
}
}
private void moveRight()
{
if (transform.position.x+ PLAYER_MOVE_VAL < Screen.width)
transform.position = Vector3.Lerp(transform.position, new Vector3((transform.position.x + PLAYER_MOVE_VAL), transform.position.y, transform.position.z),2f);
}
private void moveLeft()
{
if (transform.position.x - PLAYER_MOVE_VAL > 0)
transform.position = Vector3.SmoothDamp(transform.position, new Vector3(transform.position.x -(PLAYER_MOVE_VAL ), transform.position.y, transform.position.z), ref vector, 2f);
}
Also, when you post a question, please use code tags, and clearly define what it is you’re trying to do. For example, we don’t know whether the object should move only while a key is pressed, or whether a brief keypress should move the player to the “next position” on a grid or something, or what.
EDIT: Also also, most of the time when a newbie thinks they need to use Lerp, what they should actually be using is MoveTowards.
I have a diffrent case than documentation says. I want to make it move smoothly(if it can fit in the window horizontally) after pressed the key. I try to do it using flag but still the move is instant (I try several speed values). Thanks for code tags hint, I cannot find it on the editor
public Transform endMarker;
void Start () {
endMarker = transform;
}
private static readonly float PLAYER_MOVE_VAL = 150f;
private bool move;
private float step = 0f;
private float speed =50;
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
moveLeft();
if (Input.GetKeyDown(KeyCode.RightArrow))
{
if (endMarker.position.x + PLAYER_MOVE_VAL < Screen.width) {
move = true; //set up flag
endMarker.position += new Vector3(PLAYER_MOVE_VAL, 0);
}
}
if (transform.position != endMarker.position) move = false; //reset flag
if (move)
{
step += Time.deltaTime * speed; //amount
transform.position = Vector3.Lerp(transform.position, endMarker.position, step);
}
}
It’s still not entirely clear what you’re trying to do. But it’s clear you’re misusing Lerp. Any time you see code of the form “Foo = Lerp(Foo, endValue, step)”, it is almost certainly wrong (and it should be using MoveTowards instead, which actually works the way beginners often expect Lerp to).
So, what exactly are you trying to do? Do you just want to move between two positions — a “left” position and a “right” position, with animated motion in between? What is PLAYER_MOVE_VAL supposed to represent? And what is endMarker for (in this code, it appears to be just another word for this.transform)?
@JoeStrout as you said I want to move between two position (if able). PLAYER_MOVE_VAL is the amount of pixels that player moves after key pressed. I try using MoveToward but ive got the same issue that when Im using Lerp- on the small value of step my player moves a little bit and on the big value of step the player moves instantly.
private static readonly float PLAYER_MOVE_VAL = 150f;
private bool move;
private float step = 0f;
private float speed =10;
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, new Vector3((transform.position.x - PLAYER_MOVE_VAL), transform.position.y, transform.position.z), step);
}
}
That’s certainly doable, but…
…this is saying something completely different. Compare these two behaviors. The first one (above) would be like this:
- We define two positions, say X=0 and X=150. The player is initially at X=0.
- LeftArrow is pressed; nothing happens because we are already in the left position.
- RightArrow pressed: player object slides smoothly to X=150.
- RightArrow pressed again; nothing happens because we are already in the right position.
- LeftArrow pressed: player object slides smoothly back to X=0.
That is what “moving between two positions” means. But I think, based on your second statement and your code, that what you actually want is something like, player moves to any position that’s a multiple of PLAYER_MOVE_VAL, for example:
- Player is initially at X=0.
- LeftArrow pressed: player object slides smoothly to X=-150.
- RightArrow pressed: player object slides smoothly back to X=0.
- RightArrow pressed again: player object slides smoothly to X=150.
- LeftArrow pressed: player object slides smoothly back to X=0.
Please try to be precise when explaining what you want. If you can’t explain it, there is little hope of coding it.
Yes, that’s because you’re only doing it once. The whole point of these methods is that they change a value a little bit. To animate something you change it a little bit on each frame, over an extended period of time so the user can see it changing.
Here’s code for the second behavior above.
[Tooltip("How far we move on each keypress")]
public float stepSize = 150;
[Tooltip("How fast we move, in units/second")]
public float speed = 100;
// What position we're currently animating toward
float targetX;
void Update() {
if (Input.GetKeyDown(KeyCode.LeftArrow)) targetX -= stepSize;
if (Input.GetKeyDown(KeyCode.RightArrow)) targetX += stepSize;
Vector3 pos = transform.position;
pos.x = Mathf.MoveTowards(pos.x, targetX, speed * Time.deltaTime);
transform.position = pos;
}