Syntax Cache
BlogMethodFeaturesHow It WorksBuild a Game
  1. Home
  2. Cheat Sheets
  3. GDScript
  4. GDScript Vectors Cheat Sheet
GDScriptCheat Sheet

GDScript Vectors Cheat Sheet

Quick-reference for Godot 4 vector math. Each section includes copy-ready snippets with inline output comments using real game scenarios.

On this page
  1. 1Creating Vectors
  2. 2Vector Arithmetic
  3. 3Length and Distance
  4. 4Normalizing Vectors
  5. 5Direction and Aiming
  6. 6Dot Product
  7. 7Cross Product (Vector3)
  8. 8Lerp and Smooth Movement
  9. 9Angle Methods
  10. 10Bounce, Reflect, and Slide
Creating VectorsVector ArithmeticLength and DistanceNormalizing VectorsDirection and AimingDot ProductCross Product (Vector3)Lerp and Smooth MovementAngle MethodsBounce, Reflect, and Slide

Creating Vectors

Vector2 holds x/y, Vector3 holds x/y/z. Both are value types (passed by copy).

Vector2 basics
var pos := Vector2(100, 200)
var origin := Vector2.ZERO       # => (0, 0)
var right := Vector2.RIGHT       # => (1, 0)
var up := Vector2.UP             # => (0, -1)  # Y-down in Godot 2D
Vector3 basics
var pos := Vector3(1, 2, 3)
var origin := Vector3.ZERO       # => (0, 0, 0)
var forward := Vector3.FORWARD   # => (0, 0, -1)  # -Z is forward
Vector2 from angle
# Create a direction vector from an angle (radians)
var angle := deg_to_rad(45.0)
var dir := Vector2.from_angle(angle)
# dir => roughly (0.707, 0.707)

Vector Arithmetic

Vectors support component-wise addition, subtraction, and scalar multiplication.

Add and subtract
var a := Vector2(3, 4)
var b := Vector2(1, 2)
var sum := a + b       # => (4, 6)
var diff := a - b      # => (2, 2)
Scalar multiply and divide
var v := Vector2(3, 4)
var scaled := v * 2.0    # => (6, 8)
var halved := v / 2.0    # => (1.5, 2)
Apply velocity to position
# In _physics_process:
var speed := 200.0
var direction := Vector2.RIGHT
velocity = direction * speed
# CharacterBody2D.move_and_slide() uses velocity automatically

Length and Distance

Use length() for magnitude, distance_to() between two points. Prefer squared versions when comparing.

length() and length_squared()
var v := Vector2(3, 4)
v.length()           # => 5.0
v.length_squared()   # => 25.0  (avoids sqrt — faster)
distance_to()
var player_pos := Vector2(100, 200)
var enemy_pos := Vector2(400, 600)
var dist := player_pos.distance_to(enemy_pos)
# dist => 500.0
Range check with squared distance (performance)
var detection_range := 300.0

# FAST: compare squared distances (no sqrt)
if global_position.distance_squared_to(target.global_position) < detection_range ** 2:
    chase_target()

Always use distance_squared_to() in _process/_physics_process for performance. Avoid sqrt every frame.

Normalizing Vectors

A normalized vector has length 1. Essential for consistent movement speed regardless of direction.

normalized() returns a unit vector
var raw := Vector2(3, 4)
var unit := raw.normalized()
# unit => (0.6, 0.8)  length => 1.0
Prevent diagonal speed boost
# Without normalize: diagonal is ~1.41x faster
var input := Vector2(
    Input.get_axis("move_left", "move_right"),
    Input.get_axis("move_up", "move_down")
)
# Normalize so diagonal speed matches cardinal
if input.length() > 0:
    input = input.normalized()
velocity = input * speed
is_normalized() check
var dir := Vector2(1, 0)
dir.is_normalized()   # => true

var raw := Vector2(3, 4)
raw.is_normalized()   # => false

Direction and Aiming

direction_to() returns the normalized direction from one point to another. Perfect for aiming and AI.

direction_to() for enemy AI
var dir := global_position.direction_to(player.global_position)
# dir is already normalized — length 1
velocity = dir * chase_speed
Aim a projectile toward the mouse
func shoot() -> void:
    var bullet := bullet_scene.instantiate()
    var aim_dir := global_position.direction_to(get_global_mouse_position())
    bullet.direction = aim_dir
    get_parent().add_child(bullet)
Look at a target (rotate sprite)
# Point the sprite toward the enemy
var dir := global_position.direction_to(enemy.global_position)
rotation = dir.angle()  # angle() returns radians

Dot Product

The dot product tells you how aligned two vectors are. 1 = same direction, 0 = perpendicular, -1 = opposite.

Basic dot product
var a := Vector2(1, 0)
var b := Vector2(0, 1)
a.dot(b)   # => 0.0  (perpendicular)

var c := Vector2(1, 0)
a.dot(c)   # => 1.0  (same direction)
Field-of-view check (is enemy in front?)
var facing := Vector2.from_angle(rotation)
var to_enemy := global_position.direction_to(enemy.global_position)

if facing.dot(to_enemy) > 0.5:  # ~60 degree cone
    can_see_enemy = true
Detect if target is behind
var facing := transform.basis_xform(Vector2.RIGHT)
var to_target := global_position.direction_to(target.global_position)

if facing.dot(to_target) < 0:
    # Target is behind us — can't attack
    turn_around()

Cross Product (Vector3)

The cross product returns a vector perpendicular to both inputs. Only available on Vector3.

Basic cross product
var right := Vector3(1, 0, 0)
var up := Vector3(0, 1, 0)
var forward := right.cross(up)
# forward => (0, 0, 1)
Calculate surface normal
# Given three vertices of a triangle
var edge1 := vertex_b - vertex_a
var edge2 := vertex_c - vertex_a
var normal := edge1.cross(edge2).normalized()
Determine left/right side (2D workaround)
# Vector2 has cross() returning a float (the Z component)
var forward := Vector2(1, 0)
var to_target := Vector2(1, 1).normalized()
var cross := forward.cross(to_target)
# cross > 0 => target is to the left
# cross < 0 => target is to the right

Lerp and Smooth Movement

lerp() interpolates between two vectors. Use it for smooth camera tracking, UI animations, and easing.

Basic lerp
var start := Vector2(0, 0)
var end := Vector2(100, 100)
var mid := start.lerp(end, 0.5)
# mid => (50, 50)
Smooth camera follow
# In camera _physics_process:
var target_pos := player.global_position
global_position = global_position.lerp(target_pos, 5.0 * delta)

Multiply weight by delta for frame-rate independent smoothing.

Smooth enemy approach
func _physics_process(delta: float) -> void:
    var target := player.global_position
    global_position = global_position.lerp(target, 3.0 * delta)

    # Stop jittering when close enough
    if global_position.distance_to(target) < 2.0:
        global_position = target

Angle Methods

Convert between vectors and angles. All angle methods use radians.

angle() — vector to angle
var dir := Vector2(1, 1).normalized()
dir.angle()   # => 0.785...  (PI/4, i.e. 45 degrees)
angle_to() — angle between two vectors
var a := Vector2.RIGHT
var b := Vector2.UP
a.angle_to(b)   # => -1.5708  (-PI/2, i.e. -90 degrees)

angle_to() is signed: positive = clockwise in Godot 2D (Y-down).

Rotate a vector
var dir := Vector2.RIGHT
var rotated := dir.rotated(deg_to_rad(90))
# rotated => roughly (0, 1)  — 90 degrees clockwise
Spread pattern for projectiles
func shoot_spread(count: int, spread_angle: float) -> void:
    var base_dir := global_position.direction_to(get_global_mouse_position())
    var step := spread_angle / (count - 1)
    var start_angle := -spread_angle / 2.0

    for i in range(count):
        var angle := start_angle + step * i
        var dir := base_dir.rotated(deg_to_rad(angle))
        spawn_bullet(dir)

Bounce, Reflect, and Slide

Built-in methods for physics-style vector operations against surfaces.

bounce() — mirror off a surface
var velocity := Vector2(1, -1)
var wall_normal := Vector2(0, 1)  # floor
var bounced := velocity.bounce(wall_normal)
# bounced => (1, 1)  — reflected off the floor
reflect() — opposite of bounce
var velocity := Vector2(1, -1)
var normal := Vector2(0, 1)
var reflected := velocity.reflect(normal)
# reflected => (-1, 1)

bounce() is what you usually want for game physics. reflect() flips both components.

slide() — project along a surface
# Remove the component going into the wall
var velocity := Vector2(3, -2)
var wall_normal := Vector2(0, 1)
var slid := velocity.slide(wall_normal)
# slid => (3, 0)  — slides along the floor
Learn GDScript in Depth
GDScript Movement Practice →GDScript Projectiles Practice →
Warm-up1 / 2

Can you write this from memory?

Create a Vector2 called spawn_position with x=100 and y=200 for placing an enemy.

See Also
Tweens →Input Handling →

Start Practicing GDScript

Free daily exercises with spaced repetition. No credit card required.

← Back to GDScript Syntax Practice
Syntax Cache

Build syntax muscle memory with spaced repetition.

Product

  • Pricing
  • Our Method
  • Daily Practice
  • Design Patterns
  • Interview Prep

Resources

  • Blog
  • Compare
  • Cheat Sheets
  • Vibe Coding
  • Muscle Memory

Languages

  • Python
  • JavaScript
  • TypeScript
  • Rust
  • SQL
  • GDScript

Legal

  • Terms
  • Privacy
  • Contact

© 2026 Syntax Cache

Cancel anytime in 2 clicks. Keep access until the end of your billing period.

No refunds for partial billing periods.