Function to gradually go from one value to another?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By eyeEmotion

Hi,

I’m new to Godot and executing game-development in general. I’m better skilled at graphic design (graphics and 3D) than I am at programming (got some programming skills, but didn’t maintain it very well).
I have a project going on to learn all this and in the process create a game I like.

Currently I’m stuck with the script of my camera. I want to change the FOV when the car goes over a certain speed. For this I already got 2 working codes:

  • one that changes the FOV gradually over a set time

set_fov(get_fov() + follow_this.fwd_mps * delta * spdChangeFOV)

  • and one that changes the FOV as speed goes up.

set_fov( (follow_this.fwd_mps/follow_this.topspeed) * maxFOV )

“Problem” that occurs for me, when the FOV broadens, the car looks further away. So when the FOV goes up, I also want to bring the camera closer and lower, so that the only thing that appears to be happening for the player, is the change in FOV, but the car would still be the same size on screen.
My camera script is from somebody else, which I’m building onto. There are 2 variables (target_distance and target_height) which need to change gradually from one set value to another (and back), so the camera effect is a smooth transtion for the player. Now obviously the camera just jumps from one view to another.

This is what I have now (example of the code which makes the changes over a set time):
if (follow_this.fwd_mps > 120): if (get_fov() < maxFOV): set_fov(get_fov() + follow_this.fwd_mps * delta * spdChangeFOV) target_distance = 2.5 target_height = 0.5 else: if (get_fov() > minFOV): set_fov(get_fov() - follow_this.fwd_mps * delta * spdChangeFOV) target_distance = 4.0 target_height = 1.0

So is there a function in Godot that gradually changes one given value to another given value, over a certain amount of time (or in another cas, when speed of the car increases/decreases).

If gisthub works here, this is currently the script:

Thanks in advance.
Cheers

:bust_in_silhouette: Reply From: jHyde

HI

linear_interpolate() is probably what your looking for.

value1
value2
speed = 0.5

value1.linear_interpolate(value2, speed * delta)

Hope that’s helpful

Ok, I’m going to try that. Was trying linear_interpolate, but most of my errors seem to come from not knowing how to apply the code.

I also just noticed one part of my code doesn’t work as intended. And that I should put all this code in the _physics_process. I noticed that if I crash the car, there are not physics to process anymore and it stops changing the FOV.
So I probably put it in a seperate function and call that function in physics_process? So that the FOV keeps going to down to the regular FOV, when crashing?

eyeEmotion | 2020-04-09 10:05

I’m probably implementing it wrong, but I get an error:

  • Invalid call. Nonexistant function ‘linear_interpolate’ in base ‘float’.

Part of the code I did:

func _physics_process(delta):
...
# change FOV at 150km/h
if (follow_this.fwd_mps > 150):
if (get_fov() < maxFOV):
set_fov(get_fov() + delta * 7)
target_distance.linear_interpolate(2.5, spdChangeFOV * delta)
else:
if (get_fov() > minFOV):
...

eyeEmotion | 2020-04-09 11:28

:bust_in_silhouette: Reply From: Blackthorn

You could also use the lerp function:
lerp(from, to, weight)

Ok, I’m going to try that again. I have tried this, but most of my errors seem to come from not knowing how to apply the code. So I should go like (currentFOV, maxFOV, something * speedCar) ?

I also just noticed one part of my code doesn’t work as intended. And that I should put all this code in the _physics_process. I noticed that if I crash the car, there are not physics to process anymore and it stops changing the FOV.
So I probably put it in a seperate function and call that function in physics_process? So that the FOV keeps going to down to the regular FOV, when crashing?

eyeEmotion | 2020-04-09 10:07

AFAIK it would be the best to put the lerp function into the _process function. And yes, you should probably go like FOV = lerp(currentFOV, maxFOV, weight), and remember to call the lerp function not only once. E. g. lerp(1, 3, 0.5) would just return ‚2‘ ((3-1)*0.5) and not automatically interpolate all the steps.

Blackthorn | 2020-04-09 11:14

The lerp-function worked for the target_distance and target_height.
spdChangeFOV set to 0.01

if (follow_this.fwd_mps > 150):
	if (get_fov() < maxFOV):
		set_fov(lerp(get_fov(), maxFOV, follow_this.fwd_mps * delta * spdChangeFOV))
		target_distance = lerp(target_distance, 2.5, spdChangeFOV)
		target_height = lerp(target_height, 0.5, spdChangeFOV)
else:
	if (get_fov() > minFOV):
		set_fov(lerp(get_fov(), minFOV, follow_this.fwd_mps * delta * spdChangeFOV))
		target_distance = lerp(target_distance, 4.0, spdChangeFOV)
		target_height = lerp(target_height, 1.0, spdChangeFOV)

This kinda works kinda works for the FOV, but can’t get it dependent on the the speed.

With lerp(), I can probably leave out the “if (get_fov() < maxFOV):” and the “if (get_fov() > minFOV):” somehow, if I want to make it dependent on the speed of the car?

What I’m actually trying to achieve is to trigger this camera-change from a certain speed on, ie 150 km/h. Below this the camera FOV should stay the minFOV. Beyond that point, the camera FOV (together with the target distance and height) should gradually change, and the topspeed (ie 200 km/h) being the maxFOV.
And everything in between propotionally between those value. ie when speed is around 170 km/h, the FOV would be around 82, when the speed is around 185 km/h, the FOV could be around 91 or something.

Don’t know if that is what the lerp function is for also?

What do you mean by not calling the lerp-function once?
Also, so the _process function is at the same level as _physics_process? And I don’t have to call it or anything? I can just put the code I have (at the top of this message) and paste it in that _process function?

Cheers and thanks for the help.

eyeEmotion | 2020-04-09 12:03

Maybe I got you wrong. The lerp function interpolates from value 1 to value 2 with the weight controlling the speed of the interpolation. If you want to set the cameras FOV poportional to the speed, maybe try setting the ‚to‘ parameter of the lerp function to the FOV corresponding to the current speed, like

set_fov(lerp(get_fov(), follow_this.fwd_mps*maxFOV*some_value, weight*delta)

I hope this somehow helps!

Blackthorn | 2020-04-09 12:41

Hi Blackthorn,

sorry for the late reply. I divide my time between programming the game and modeling the game. And no, you didn’t get anything wrong, my initial question was limited just to what you answered. Because I didn’t know if such a “large scope” of a question would get an answer.
Thnx for the code, I will try it out. That some_value, what is that intended for?
So it’s actually using functions inside functions. Can’t believe I forgot a technique like that.

I’m beginning to notice that there are a lot of properties in my game that are dependant on the speed of the car. Like currently I also implement that at certain speeds, the limit of the steering gets smaller, so you have a better handling at higher speeds and more turn at smaller speeds. But as of now, you still can see the “steps”, because I say "At 25km/h, limit 5. At 80km/h, limit at 3, … "
And I have several properties like that, that need to change depending on speed. I want to try it with the engine_force aswell, to eliminate not being able to drive uphill at lower speeds.
I don’t know if it is possible to create a function like that for all properties, because different properties are set in different ways, like set_fov() versus engine_force = 500 for example.
But it’s giving me some stuff to think about and a learning process along the way.

Cheers

eyeEmotion | 2020-04-19 16:34