#Making player move in 2D using Lerp

1 messages · Page 1 of 1 (latest)

dire veldt
#

hi

#

anywaay

#

here's currently what my goal is

#

eh one sec

fringe igloo
#

might wanna formalize your question in one paragraph

dire veldt
#

I want it such that if the player holds down a key, a speed value is lerped until it hits a max speed, and holds that same speed until the key is let go, after which it lerps back to it's previous value (before the keypress)

#

here's my code so far (broken)

fringe igloo
#
float targetFloat = keyPressed ? 1f : 0f;
myFloat = Mathf.Lerp(myFloat, targetFloat, Time.deltaTime * lerpSpeed);
dire veldt
fringe igloo
#

or MoveTowards or whatever smoothing/lerping you want

night bane
dire veldt
#

and how exactly do i control lerpspeed

#

i would like it so that it lerps from start to finish in around 0.5 seconds

night bane
#

There's no such thing as lerp speed. Lerp is a function that returns a value based on the parameters you give it.

dire veldt
#

right then is there a way i can use time.deltaTime inside the lerp and a timer of sorts

#

i attempted that on my script but couldn't figure out how to put it inside the lerp function

night bane
fringe igloo
#
private float transition;
[SerializeField] private float transitionSpeed = 10f;
[SerializeField] private float minValue = 3f, maxValue = 5f;
public float myFloat;

void UpdateMyFloat()
{
  // Transition value moves between 0..1 depending on key press state
  float  transitionTarget = keyPressed ? 1f : 0f;
  transition = Mathf.MoveTowards(transition, transitionTarget, Time.deltaTime * transitionSpeed);

  // Update myFloat to be between min and max value, in range of transition
  myFloat = Mathf.Lerp(minValue, maxValue, transition);
}
dire veldt
#

where is the myFloat used in the script?

night bane
dire veldt
#

and t goes inside the lerp, right?

night bane
#

Basically what Osmal shared.

dire veldt
#

i'll try to implement it

#

wait

#

does Mathf.MoveTowards work like lerp but uses time values?

night bane
#

None of them have to use time values. They are just functions that take input and return a value.

#

They just do simple math, like x = a + b.

#

You can use time in your calculations, but that's not gonna change the fact that they just do simple math every frame

fringe igloo
dire veldt
#

okay i understood the script i think

#

can i just say it from what i understood just to make sure

#

transition = Mathf.MoveTowards(transition, transitionTarget, Time.deltaTime * transitionSpeed);
this line is instantanouesly set to 0 if button not pressed, or slowlys goes to 1 (but never reaches it(??)) if the button is pressed

fringe igloo
#

I updated the snippet a bit so its easier to tell whats local vars and whats member vars

fringe igloo
#

and it does reach the target value yes

#

then we use transition to "sample" a value between minValue and maxValue

#

(with Mathf.Lerp)

dire veldt
#

does it move at a rate of 0.01

#

like if I'm running at 60fps then time.deltaTime ~ 0.01 right

fringe igloo
dire veldt
#

yes

fringe igloo
#

if you use Time.deltaTime as t in MoveTowards, it will take 1 second to reach the value

#

if you use Time.deltaTime * 10, it will take 0.1 seconds

#

(1 / 10)

#

does it make sense?

dire veldt
#

wait

#

yes

fringe igloo
#

also this is all called from Update

dire veldt
#

yeah i got that

#

last question

#

if i had used a constant, say 0.5 value in t

#

for Lerp()

#

does that mean all I would get is just the halfway point between 0 and 10 (if they there a and b in lerp)

#

and that's why t needs to change?

fringe igloo
#

check these

#

oh ffs the bot keeps removing my message lol

#

anyway look at Mathf.MoveTowards and Mathf.Lerp in docs

dire veldt
#

lol

fringe igloo
#

(Vector3/Vector2 also have similiar functions)

dire veldt
#

i did try to look at them but it's my fault cause i did kinda skim them

#

so basically both of them are just another way of writing a function f(x) where x is t, and f returns the value x% towards b from a

fringe igloo
#

they are functions, with differing functionality

#

although they can be used for similiar use case

dire veldt
#

i see

fringe igloo
dire veldt
#

wait i'm lost again

#

OH

#

yeah that's what i wanted to ask

#

if i used something like Mathf.Smoothstep(0,1,t)

fringe igloo
#

Mathf.MoveTowards(0f, 10f, 3f) returns 3f

dire veldt
#

for the transitionTime that goes in Lerp

fringe igloo
#

Mathf.MoveTowards(3f, 10f, 3f) returns 6f

dire veldt
#

one last question

fringe igloo
dire veldt
#

does Time.deltaTime say more or less the same

#

because isn't it calculating the value time between current and last frame

fringe igloo
#

ideally, your FPS would stay as stable as possible

dire veldt
#

okay with like a stable 60fps Time.deltaTime returns 1/60

night bane
dire veldt
#

so how did u use it in MoveTowards?

#

because if it's more or less constant, wouldn't movetowards return the same value every time

night bane
dire veldt
#

OH

#

u like

#

what's the word

#

REASSIGNED IT

#

OHHHHHH

#

so like

#

first time if u had x = mathf.movetowards(0,1,Time.dtime)

#

x = 0.1 for first frame
x = 0.2 for second

#

and so on right?

fringe igloo
#

nah you would do x = Mathf.MoveTowards(x, 1, Time.deltaTime)

#

notice x as first argument

dire veldt
#

oh yeah mb

#

that's what i meant

#

but for smoothstep, i can't do that, since t is a percent

#

so does that mean i need an inbuilt timer?

fringe igloo
#

you could change this:

  myFloat = Mathf.Lerp(minValue, maxValue, transition);

to this:

  myFloat = Mathf.Lerp(minValue, maxValue, Mathf.SmoothStep(0f, 1f, transition));
#

so that you sample with a smoothed t, not linear

#

otherwise, smoothstep doesnt really help here

dire veldt
#

oh even smarter

#

from now one Mathf.Movetowards is my bae

#

going to use it instead of timers

fringe igloo
#

now go explore 😎

#

this is all a bit easier to understand when you visualize it

dire veldt
#

yeah i tried to

#

by drawing lines on my pencil

#

it did not work out

#

okay here's my code

#
        float hAxis = Input.GetAxis("Horizontal");
        
        float transitionTarget = hAxis != 0 ? 1f : 0f;
        float targetSpeed = hAxis != 0 ? 10f : 0f;
        float transitionTime = 0;
        transitionTime = Mathf.MoveTowards(transitionTime,transitionTarget,Time.deltaTime);

        moveSpeed = Mathf.LerpUnclamped(moveSpeed, targetSpeed,Mathf.SmoothStep(0,1,transitionTime));
        return moveSpeed;
#

so moveSpeed does increase, but letting of the button doesn't seem to bring it back

#

any idea why?

fringe igloo
#

try Input.GetAxisRaw

#

instead of getaxis

#

reason: GetAxis has some smoothing in it, and may never reach 0

dire veldt
#

ah

#

i'm learning so much

#

and feeling dumber by the second

fringe igloo
#

alternatively you can replace hAxis != 0 with Mathf.Abs(hAxis) > 0.001f or something

#

anyway i got some stuff to do

dire veldt
#

thank you so much for helping

#

bye bye

dire veldt
#

okay i'm lost again

#

;-;

fringe igloo
#

paste code in a paste site or something

dire veldt
#

no the only thing i want to do now is

#

make it so that all this happens over the course of 3 seconds, instead of the default 1

fringe igloo
#

divide Time.deltaTime by the amount of seconds

dire veldt
#

yeah but then

fringe igloo
#

well what do you want to happen over 3 seconds?

#

the transition from 0 to 1?

dire veldt
#

no

#

the lerp

#

i can't multiply mathftowards right

#

wait

fringe igloo
#

can you stop typing vertically please?

dire veldt
#

oh yeah sorry my bad.

fringe igloo
#

so transition length determines lerp length

dire veldt
#

okay that makes sense.
if i'm correct, to should take 1/Time.deltaTime * some var frames to finish the transition correct

fringe igloo
#

you can have a float transitionDuration and then do
transitionTime = Mathf.MoveTowards(transitionTime, transitionTarget, Time.deltaTime / transitionDuration);

#

(i just added the / transitionDuration part to your code)

dire veldt
#

wait it's that simple?

#

i don't know whether to cry or rage or be happy

#

okay it didn't work

#

yes the movetowards functions takes x seconds to reach one, but the lerp function hits the max value much much faster

fringe igloo
#

would be cool if you show the code 🤷‍♂️

dire veldt
#
        // Transition value moves between 0..1 depending on key press state
        float transitionTarget = hAxis ? 1f : 0f;
        float targetSpeed = hAxis ? 10f : 0f; 
        transitionTime = Mathf.MoveTowards(transitionTime,transitionTarget,Time.deltaTime / accelerationTime);
        if (transitionTime > 0 && transitionTime < 0.99f) {
            timer += Time.deltaTime;   
        }
        // Update myFloat to be between min and max value, in range of transition
        moveSpeed = Mathf.LerpUnclamped(moveSpeed, targetSpeed,transitionTime);

        return moveSpeed;
fringe igloo
#

wait no.

#

this is wrong
moveSpeed = Mathf.LerpUnclamped(moveSpeed, targetSpeed,transitionTime);

#

and not like in my example

dire veldt
#

oh

fringe igloo
#

the idea was
moveSpeed = Mathf.LerpUnclamped(minMoveSpeed, maxMoveSpeed, transitionTime);

dire veldt
#

but then how can i do it so that if the player was already moving at a speed it accelerates/decceleatres

fringe igloo
#

you wanted a switch that transitions from 0 to 1

#

or from x to y

dire veldt
#

i kinda wanted it to go from x to y, then back to x

#

depending on whether the key is pressed

fringe igloo
#

...?

#

thats what my code does

#

x is minSpeed and y is maxSpeed

dire veldt
#

yeah but letting go of the key doesn't bring it back

#

it keeps it there

fringe igloo
#

before saying it doesnt work

#

lol...
-asks for help
-gets solution
-implements solution wrong
-doesnt correct the solution
-blames solution

dire veldt
#

it goes from 2 to 10

#

then 0 to 2

#

okay that's a fair critique sorry for acting like the toxic noob

#

maybe i should just give up for now

#

work on another part

#

sorry for wasting your time

fringe igloo
#

@dire veldt just tested this and it does work

#

    float transitionTime;
    float moveSpeed;
    float minSpeed = 2f,
        maxSpeed = 10f,
        accelerationTime = 2f;
    void Test()
    {
        bool hAxis = Input.GetKey(KeyCode.A);

        float transitionTarget = hAxis ? 1f : 0f;
        transitionTime = Mathf.MoveTowards(transitionTime, transitionTarget, Time.deltaTime / accelerationTime);

        moveSpeed = Mathf.LerpUnclamped(minSpeed, maxSpeed, transitionTime);

        print("Speed: " + moveSpeed);
    }
    private void Update()
    {
        Test();
    }
dire veldt
#

:O

fringe igloo
#

it moves from 2 to 10 in 2 seconds, and back when you release

dire veldt
#

I currently have to do something but I'll try it later

#

If it does work thank you so much

fringe igloo
#

yeah I just wanted to check that nothing is wrong with what i gave you

#

but you should add just that to an object, then work your way up there, see where it breaks for you

dire veldt
#

Have u been doing gamdev for a long time,?

#

U seem rlly good

fringe igloo
#

Ive been dev for ages, Unity programming just a few years tho

#

not an expert but passionate hobbyist

dire veldt
#

Well I have to go now but again tysm

dire veldt
#

hey @fringe igloo

#

if ur not busy

#

I finally made my 100% own script for the walk cycle

#

the player moves at a constant rate towards the max speed, while the button is being pressed

#

i'm proud of it :)

#
    void RunAndWalk() {
        bool isMoving = hAxis != 0;
        float accelerationRate = (maxSpeed * Time.deltaTime)/timeToMaxSpeed;
        print(isMoving);
        if (isMoving) {
            playerSpeed = Mathf.MoveTowards(playerSpeed, maxSpeed * Mathf.Sign(hAxis), accelerationRate);
        } else if (playerSpeed != 0) {
            playerSpeed -= Mathf.MoveTowards(0,playerSpeed,accelerationRate);
        }