# Manually rotate KinematicBody's local UP-axis toward World's UP-axis ?

Attention Topic was automatically imported from the old Question2Answer platform.

My object can have any(unknown) rotation in the world.

I need to interpolate this object’s local UP-axis, towards the World’s UP-axis, without touching the object’s other local rotations.

Anyway, all I seem to manage, is interpolating every object-axis towards every World-axis at the same time, effectively aligning my object to the World, like a well trained nazi-soldier.

I’m using this code to accomplish my faliure:

``````var TopQuat:Quat = Quat(0,0,0,1)
transform.basis = Basis(Quat(transform.basis).slerp(TopQuat,delta))
``````

Any hints for isolating this interpolation to my object’s local UP-axis?

You could have 2 lerps, one for X and one for Z both going from their initial value to 0.

Mmmm yes … I tried that, but I’m unsure about what property to do the lerping against.

If I lerp over transform.basis.x/z, like this:

``````transform.basis.x = lerp(transform.basis.x,Vector3(1,0,0),delta)
``````

… I get absolutely crazy psychedelic warping of my object’s dimensions, giving me ideas for a LSD-simulator-game

Ole | 2019-05-06 17:59

You need to get the `transform.basis.x` starting value.

var x_start = transform.basis.x

transform.basis.x = lerp(x_start ,0, delta)

Make sure `x_start` doesn’t change, then again a LSD-simulator-game sounds awesome `transform.basis.x = randf...`

Magso | 2019-05-06 18:14

Yours and my code, does exactly the same job … I don’t need your x_start variable, as I stick the transform.basis.x-start-state directly into the lerp-function, and saves the result as the new (lerp’ed) value of transform.basis.x, resulting in the same functionality, with on less code line

Besides, you want to input an integer (0) as the second argument for the lerp, which isn’t allowed. It wants a Vector3, because the transform.basis.x itself is a Vector3.

A long story short … it still gives the LSD-result

Ole | 2019-05-06 18:29

Ah… I thought transform.basis was a vector3 and transform.basis.x would be a float. I’m too used to rotation_degrees. I myself would do it like this,

``````var start_rotation = [rotation_degrees.x, rotation_degrees.z]
var time : float

func _process(delta):
time += delta
if time <= 1:
rotation_degrees.x = lerp(start_rotation[0], 0, time)
rotation_degrees.z = lerp(start_rotation[1], 0, time)
``````

Not very fancy but reliable.

Magso | 2019-05-06 18:51

Wonderful … You solved my problem!

However, I don’t understand all your extra fluff-code … it isn’t necessary, and will bloat your code base.

My implementation is way simpler, and does exactly the same job:

``````rotation_degrees.x = lerp(rotation_degrees.x, 0, delta)
rotation_degrees.z = lerp(rotation_degrees.z, 0, delta)
``````

But, thanks alot!

Ole | 2019-05-06 19:09

I thought that setting a lerp every frame would have more unnecessary overhead than checking if a float is below 1. It also helps if the lerp needs to be repeated or reversed.

Magso | 2019-05-06 19:33

Fair enough.

Besides, I believe my approach yields a kind of ‘diminishing’ interpolation (reversed exponential), theoretically never reaching 0 (in reality it does), which renders lovely smooth animation, perfect for my use case,

Your approach yields linear interpolation, which is more in-line with the intended use of the function lerp().

Anyway … I’m happy, and owe you a beer, or an LSD-trip … thanks for the help

Ole | 2019-05-06 20:23