Migrating from 3.x
This is an evolving list of the main changes and “gotchas” to look out for if you’re transitioning to 4.0.
One of the biggest changes in Godot 4 is a whole bunch of renaming - of nodes, functions, and property names. Most of it is done to make things consistent or clear. Here are a few of the biggest ones to watch out for:
2D/3D nodes - In Godot 3.x, 2D nodes had the “2D” suffix, but 3D nodes had none. This has been made consistent - they all now have “2D” or “3D” suffixes. For example:
Also in the category of 3D, the
Spatialnode is renamed to
One of the most popular nodes,
KinematicBody, has been renamed to
CharacterBody3D. See below for further changes with this node’s API.
instance()function has been renamed to
global_translationin 3D, making them consistent with 2D.
Signals and Callables
Working with signals is much more streamlined in 4.0.
Signal is a native type now, so you’ll be using fewer strings, meaning you get autocomplete and error checking. This applies to functions as well, which can now be directly referenced rather than using strings.
Here’s an example of defining, connecting, and emitting a signal.
extends Node signal my_signal func _ready(): my_signal.connect(signal_handler) func _input(event): if event.is_action_pressed("ui_select"): my_signal.emit() func signal_handler(): print("signal received")
If you started using
SceneTreeTween in Godot 3.5, then you’ll be familiar with Godot 4.0’s
Tween is no longer a node. Instead, you create one-off tween animation objects whenever you need them. Once you get used to it, it’s a lot more powerful and easier to use than the old method.
The biggest change that catches people who are familiar with the 3.x version of this node is that the
playing property is gone. It’s now much more consistent with
AnimationPlayer’s usage - to automatically play an animation, you can toggle autoplay in the SpriteFrames panel. In code, use
stop() to control playback.
The biggest change in this node is in using
move_and_slide(). It no longer takes any parameters - they are all now built-in properties. This includes a native
velocity property, so you no longer need to declare your own.
TileMap node is completely overhauled for 4.0. Just about everything, from how you create
TileSets to how you draw and interact with tiles is 100% new.
Our “Using TileMaps” guide is coming soon.
There are a few changes to GDScript’s built-in random number generator functions:
You no longer need to call
randomize()- this is automatic. If you do want repeatable “randomness”, use
seed()to set it to a preselected value.
rand_range()is now replaced with either
randf_range()(for floats) or
When casting rays in code, there’s a new API.
PhysicsDirectSpaceState[2D|3D].intersect_ray() now takes a special object as a parameter. This object specifies the ray properties. For example, to cast a ray in 3D:
var space = get_world_3d().direct_space_state var ray = PhysicsRayQueryParameters3D.create(position, destination) var collision = space.intersect_ray(ray) if collision: print("ray collided")