Direction vectors in Godot Engine

There is a previous article where we discussed movement and rotation basics of Godot Engine. In this article, we are going to look at the rotation of game objects using direction vectors in Godot Engine in detail.

We know that rotations are expressed in Euler angles. For 2D games, this is enough because there are only two axes in the world and the rotation will be along the z-axis. In 3D, setting them in Euler will be disastrous if there are multiple axes are involved because after some rotations, Gimbal Lock comes into place and our rotations will be out of control. So for 3D rotations, we use Quaternion instead of Euler. If you don’t know what is a Quaternion, then I say you don’t need to. We only need to know how to convert between Euler and Quaternion and how to specify the rotation as a Quaternion etc.

3D rotation of a game object is said as orientation. Because most of the times a game object rotation will depend on external factors such as movement direction, attack direction, enemy positions etc. So we calculate the Vector3 direction at which the game object should orientate.

Local directional vectors

In Unity3D, there are two vector properties in the Transform component. But in Godot, there are no named directional vectors. But the same can be accessed from the transform basis. To know more about how transform and matrix are useful in Godot engine, you can visit the official tutorial page here.

Also Read:   Godot Engine game tutorial for beginners – Create a 2D Racing Game 2

The directional vectors can be accessed from the transform basis like this.

Forward: -get_transform().basis.z
Left: get_transform().basis.x
Up: get_transform().basis.y

Moving an object in a direction

First, we need to find the motion vector by multiplying the unit direction vector with a speed value. We can then add the motion vector to its position to get the object moving in that direction.

var speed = 5
var dir = get_transform().basis.x
var motion = dir * speed
var pos = get_translation()
set_translation(pos + motion)

Another way using the transform origin.

var speed = 5
var t = get_transform()
var dir = t.basis.x
var motion = dir * speed
t.origin += motion
set_transform(t)

Another way using translate

var speed = 5
var dir = get_transform().basis.x
var motion = dir * speed
translate(motion)

Find the direction vector to another object

var dir = (target_obj.get_transform().origin - get_transform().origin).normalized()

To get the direction towards another object, we should subtract its position from the other object’s position. This will get the direction vector with a magnitude which is the distance between the two objects. We normalize the vector to get the direction unit vector.

Look at a direction

Godot has a built-in method to look at objects.

look_at(target_obj.get_transform().origin, Vector3(0,1,0))

The look_at method accepts the target position to rotate to. The second argument is the up vector and usually, it is the world up vector which is Vector3(0,1,0). But how can we rotate an object to a direction by passing a direction vector? It is simple, we add the direction to its position so we get a position apart from its origin in that direction.

look_at(get_transform().origin + dir, Vector3(0,1,0))

Thanks for reading, I’ll try to include some advanced tutorials that use these type of calculations.

Also Read:   Godot Engine game tutorial for beginners - Create a 2D racing game part 5

Never miss any content from Codetuto!

Subscribe to Codetuto Newsletter and be the first to recieve our latest posts and tutorials

Subscribe Now For Free

[Total: 1    Average: 4/5]
  • James Redmond

    Thanks for doing these tutes for Godot, they are excellent and much needed! Would be great to get a tutorial on applying these vectors and matrix calculations for use with the 3d kinematic body and move() function.

    • Vinod

      Thanks for your comment.
      I will do an article on how these things can be applied on a real game.

      • James Redmond

        Nice, I look forward to it…look_at(Vinod, Vector3(0, 1, 0)) 🙂