Godot Engine – Movement and Rotation basics

Godot engine is a 2d and 3d open source cross platform game engine. The beauty of it is not only can export to most of the platforms but also the editor can run on Windows, Mac and Linux. As of now, Godot engine is 2.0 beta and you can download it from the official website godotengine.org.

This post is targeted towards beginners who are coming to Godot engine from other engines. If you have no experience in any game development, you may get some help here but I recommend you to look at Godot wiki on vector maths and transformations. I believe you can apply these in advanced things like character movement, camera control etc.

Vector
A vector represents a magnitude and direction. In a game engine, a vector is used to represent a position or a direction.

3d world

Red is x axis, yellow is y and blue is z

Red is x axis, yellow is y and blue is z

Let us assume that there is a 3d world in Godot. The world is where we put all game objects and it is where the game runs.

If we add the global right vector i.e, Vector3(1,0,0) to a game object which is at the world origin(0,0,0), the object’s new position will be Vector3(1,0,0) irrespective of its rotation. It just moves on the world x axis, that’s all.

If you are coming from Unity, take note that Godot has a slight difference in the axes compared to Unity. The forward direction is not positive z, but it is negative z. So when we export from blender, make sure the forward is -z forward and y is up.

Forward is inverse z

Forward is inverse z

Every object in the game world also has its own position and a direction. This position and direction is stored as a Matrix. You only need to understand that every object has a transformation matrix which represents the position and its orientation(also the scale, but leave it for now). We can get this Matrix by calling get_transform() on an object. There is also a get_global_transform() method which returns the transformation with respect to the game world.
So if we know the transform of a game object, we can get its position and its direction. We get the position from its origin and orientation from its basis.

Also Read:   Start Developing HTML5 games in Phaser using TypeScript

Enough talk on vectors and matrices, let us jump into action

Moving in global axes
This code moves the object on the world x axis.

func _process(delta):
    t = get_transform()
    t.origin += Vector3(delta,0,0)
    set_transform(t)

By changing the origin of the transform, we can change the position of the object. Instead of using this code, godot provides a simpler method for doing this.

func _process(delta):
    global_translate(Vector3(delta,0,0))

The above code just moves the gameobject on the world x axis.
movement in global directionEven if we rotate the object, it just moves along the world x axis because the object is moved in global x axis. Global transform is independent of local position and rotation.
movement in global direction

Moving in local axes
If we want to move the object to its right side, the above code won’t work. For that we need to know the local right direction vector of the object. We can do this by,

t = get_transform()
t.origin += t.basis.x * delta
set_transform(t)

We take the right directional vector which is the transform basis.x of the object and add it to the position. Godot engine has easy and simple methods for doing this.

translate(Vector3(delta,0,0))

Here we are asking to move on its own local axes by using translate instead of global_translate. The passed Vector3(delta,0,0) is converted to its local space internally. If we want to move to the forward direction, which is -z,

translate(Vector3(0,0,-delta))

Move to a position
To move to a position, we need to get the direction vector from the object to the target position. We have a targetObject which is where we want the object to go. So, we find the direction vector by subtracting the source from the destination position. We only need the normalized vector which just represents the direction.

var dir = (get_node(targetObject).get_global_transform().origin - get_global_transform().origin).normalized()
global_translate(dir*delta)

If we want to change the speed we just multiply the delta with the speed like dir*speed*delta.

Also Read:   Creating an html5 game like concentration

Rotation of an object
Rotation is somewhat complex if we dig deep. In the editor, the rotation is represented in euler angles. It is super simple that each of the three angles represent the rotation in all angles. In 3d, multiple different euler angle rotations causes the axis rotations to appear locked. This is called Gimbal Lock. To avoid that, 3d rotations are done using Quaternions. Quaternions are used to represent the orientation of a 3d object.

If we are not going to change an object’s rotation dynamically or only rotating a single axis, then use euler angles. We can rotate an object in euler angles by rotate_x, rotate_y, rotate_z methods.

Looking at an object
Godot already has a built-in look_at method to which we can pass the target object position and the object will look to that position.

var lookPos = get_node(lookTarget).get_transform().origin
look_at(lookPos,Vector3(0,1,0))

Quaternion look at

var t = get_transform()
var lookDir = get_node(lookTarget).get_transform().origin - t.origin
var rotTransform = t.looking_at(get_transform().origin+lookDir,Vector3(0,1,0))
var thisRotation = Quat(rotTransform.basis)
set_transform(Transform(thisRotation,t.origin))

Linear Interpolation (lerp)
Lerping can calculate the value at any point between two known values. You can search more on the entire internet about linear interpolation. Let us look at an example, if we have two numbers 100 and 200, lerp at 0.5 and we get the middle of 100 and 200, which is 150. The lerp amount can vary from 0 to 1 to get the minimum and the maximum original values. In the above example 0 is 100 and 1 is 200.
Using this logic, we can lerp between two vectors to move an object just by changing the lerp amount.

var value = 0;
func _process(delta):
    t = get_transform()
    
    var start = Vector3(0,0,0)
    var end = get_node(targetObject).get_transform().origin
    var pos = start.linear_interpolate(end,value)
    value += delta

    t.origin = pos
    set_transform(t)

lerp_basic

We can see that the object moves from the origin to the targetObject position. It won’t stop because lerping is not limited to 0 and 1, we can just pass any number, 0 and 1 represents minimum and maximum values.

Also Read:   Drawing a circle using Gizmos in Unity3D

Smoothed Arrival using Lerp
We can smooth the movement of an object while reaching its target by lerping.

t = get_transform()
var end = get_node(lookTarget).get_transform().origin
t.origin = t.origin.linear_interpolate(end,delta)
value += delta
if value>1:
value = 1
set_transform(t)

lerp_smooth_arrival

Godot engine has methods for lerping between float values, Vectors and Colors.

Spherical Linear Interpolation (slerp)
Slerping is mostly used when interpolating between quaternions. This can be used to make a behaviour for a turret or something like that which rotates gradually in time.

var lookDir = get_node(lookTarget).get_transform().origin - t.origin
var rotTransform = t.looking_at(lookDir,Vector3(0,1,0))
var thisRotation = Quat(t.basis).slerp(rotTransform.basis,value)
value += delta
if value>1:
    value = 1
set_transform(Transform(thisRotation,t.origin))

slerp

Do you know how to rotate an object to its moving direction? Just create a lastPos variable which stores the last position of the object. Then in the above code, get the lookDir like this,

var lookDir = t.origin - lastPos
lastPos = t.origin

That’s all for now and hope you learned something from this. In the following posts we will build up from this and do something creative. Thanks for reading.

[Total: 4    Average: 3.8/5]
  • DutzeART

    Hey! Nice article!
    But can you help me with getting (and probably also setting) the local orientation of a 3D node in Godot? I’m not that good at math and that stuff so hopefully you guys can help me. There has to be a way… ^^

    Thanks in advance!

    • Vinod

      The set_transform and get_transform method handles the local transformations. So what you do with them is local.

      Usually in 3d games, we rarely need the rotation angles because rotations are dependent on external factors, such as look to the object’s left/right/back or look at another object, or look at moving direction etc. We use Quaternions and set the object’s orientation for this purpose.

      May be you can elaborate on what you want?

      • DutzeART

        Huhh, thank you for the really fast reply, didnt awaited that! ^^
        So to sum it up, I tested the vehicle suspension nodes in Godot and have mainly problems with limiting the vehicle rotation (to prevent overturning at fast speed, especially while driving curves). Therefore I just wanted so set the orientation of the important vehicle nodes 🙂

        Here you can see a video of the Problem (e.g. at 0:24) by Juan Linietsky 😉

        Big thanks again for your help, ur awesome!

      • DutzeART

        Hmm, my reply disappeared twice now, maybe because there was a Youtube link in it? nvm 😛

        So again:

        I tried to create a car game with Godot and used its vehicle nodes. But I had problems with the car behaviour, especially while driving fast through curves – the car overturns very fast and I wanted to limit the rotation to avoid overturning but not disabling the suspension effect as a whole.
        Apparently I can’t post a video link in this comment, alternatively you can google the video (showing my described problem with overturning) with the words “Car Model Physics at 300mph”, you should find it 🙂

        Thanks and HAPPY NEW YEAR 🙂

      • Vinod

        Happy New Year to you too..

        This car flipping is a generic problem with all car setups. Godot car physics is not that mature. If you search on Google, you can see that other engines also get this problem. In Unity, we can easily fix this problem(not a good solution but it prevents most flips) by changing the center of mass. But we can’t do that for Godot engine.

        We need to implement something like real car stabilization physics. You can read more about this in this Unity thread here.

        https://forum.unity3d.com/threads/how-to-make-a-physically-real-stable-car-with-wheelcolliders.50643/

        The actual code is so little that I think you can port it to Godot. I haven’t dived deeply into any car physics so I hope it works.

        Thanks.

      • DutzeART

        Thank you again, especially for the link to the Unity thread 🙂

  • Jonas Antunes Da Silva

    I was trying to run the code for object translation, without success. Later I discovered that its necessary to activate Idle processing calling set_process(true) inside _ready() function.

    Great tutorial.

  • Justin

    Thanks so much for this article! It was very helpful.

  • Momfus

    Thanks for do this. The Godot’s documentation is ver uncomplete and reading this I understand how get_transform() works.

  • adhi dwipa

    Ah this is what I need to understand how to manipulate object movement. Good writing easy to follow.

    • Vinod

      Thanks

  • Pingback: Create a Catch The Egg game in Godot Engine - Codetuto()

  • JTJonny

    Thanks for this, learned a lot.

    • Vinod

      Glad it helped.