Tipagem estática em GDScript¶
Neste guia, você aprenderá:
- Como usar tipos no GDScript
- Que os tipos estáticos podem ajudá-lo a evitar erros
A decisão de onde e como você usa esse novo recurso de linguagem é inteiramente sua: você pode usá-lo apenas em alguns arquivos GDScript sensíveis, usá-lo em qualquer lugar ou escrever códigos como sempre fez!
Tipos estáticos podem ser usados em variáveis, constantes, funções, parâmetros e tipos de retorno.
Nota
O GDScript digitado está disponível desde Godot 3.1.
Uma breve olhada na tipagem estática¶
With typed GDScript, Godot can detect even more errors as you write code! It gives you and your teammates more information as you're working, as the arguments' types show up when you call a method.
Imagine you're programming an inventory system. You code an Item
node, then an Inventory
. To add items to the inventory, the people
who work with your code should always pass an Item
to the
Inventory.add
method. With types, you can enforce this:
# In 'Item.gd'.
class_name Item
# In 'Inventory.gd'.
class_name Inventory
func add(reference: Item, amount: int = 1):
var item = find_item(reference)
if not item:
item = _instance_item_from_db(reference)
item.amount += amount
Outra vantagem significativa do GDScript digitado é o novo sistema de alerta. A partir da versão 3.1, Godot dá avisos sobre o seu código à medida que você o escreve: o motor identifica seções de seu código que podem levar a problemas em tempo de execução, mas permite que você decida se deseja ou não deixar o código como está. Mais sobre isso em um momento.
Static types also give you better code completion options. Below, you
can see the difference between a dynamic and a static typed completion
options for a class called PlayerController
.
You've probably stored a node in a variable before, and typed a dot to be left with no autocomplete suggestions:

This is due to dynamic code. Godot cannot know what node or value type you're passing to the function. If you write the type explicitly however, you will get all public methods and variables from the node:

No futuro, o GDScript digitado também aumentará o desempenho do código: a compilação Just-In-Time e outras melhorias do compilador já estão no roteiro!
Overall, typed programming gives you a more structured experience. It helps prevent errors and improves the self-documenting aspect of your scripts. This is especially helpful when you're working in a team or on a long-term project: studies have shown that developers spend most of their time reading other people's code, or scripts they wrote in the past and forgot about. The clearer and the more structured the code, the faster it is to understand, the faster you can move forward.
Como usar a digitação estática¶
To define the type of a variable or a constant, write a colon after the
variable's name, followed by its type. E.g. var health: int
. This
forces the variable's type to always stay the same:
var damage: float = 10.5
const MOVE_SPEED: float = 50.0
Godot tentará inferir tipos se você escrever dois pontos, mas omite o tipo:
var life_points := 4
var damage := 10.5
var motion := Vector2()
Atualmente você pode usar três tipos de… tipos:
- Embutido
- Classes e nós centrais (
Objeto
,Nó
,Area2D
,Camera2D
, etc.) - Suas próprias classes personalizadas. Veja o novo recurso: ref: class_name <doc_scripting_continued_class_name> para registrar tipos no editor.
Nota
Você não precisa escrever dicas de tipo para constantes, já que Godot o define automaticamente a partir do valor atribuído. Mas você ainda pode fazer isso para tornar a intenção do seu código mais clara.
Tipos customizados de variável¶
Você pode usar qualquer classe, incluindo suas classes personalizadas, como tipos. Existem duas maneiras de usá-los em scripts. O primeiro método é pré-carregar o script que você deseja usar como um tipo em uma constante:
const Rifle = preload("res://player/weapons/Rifle.gd")
var my_rifle: Rifle
O segundo método é usar a palavra-chave `` class_name`` quando você cria. Para o exemplo acima, o seu Rifle.gd ficaria assim:
extends Node2D
class_name Rifle
Se você usa class_name
, o Godot registra o tipo Rifle globalmente no editor, e você pode usá-lo em qualquer lugar, sem ter que previamente carregá-lo em uma constante:
var my_rifle: Rifle
Conversão de variáveis¶
A conversão de tipos é um conceito-chave em idiomas tipados. Casting é a conversão de um valor de um tipo para outro.
Imagine um Inimigo no seu jogo, que extends Area2D
. Você quer que ele colida com o Jogador, um KinematicBody2D
com um script chamado PlayerController
atrelado a ele.
Você pode verificar se este PhysicsBody2D
é o seu Jogador com a palavra-chave as
e usando os dois pontos :
novamente para forçar a variável a usar este tipo. Isso força a variável a se ater ao tipo PlayerController
:
func _on_body_entered(body: PhysicsBody2D) -> void:
var player := body as PlayerController
if not player:
return
player.damage()
As we're dealing with a custom type, if the body
doesn't extend
PlayerController
, the player
variable will be set to null
.
We can use this to check if the body is the player or not. We will also
get full autocompletion on the player variable thanks to that cast.
Nota
Se você tentar moldar com um tipo embutido e falhar, Godot lançará um erro.
Linhas seguras¶
You can also use casting to ensure safe lines. Safe lines are a new tool in Godot 3.1 to tell you when ambiguous lines of code are type-safe. As you can mix and match typed and dynamic code, at times, Godot doesn't have enough information to know if an instruction will trigger an error or not at runtime.
This happens when you get a child node. Let's take a timer for example:
with dynamic code, you can get the node with $Timer
. GDScript
supports duck-typing,
so even if your timer is of type Timer
, it is also a Node
and an
Object
, two classes it extends. With dynamic GDScript, you also
don't care about the node's type as long as it has the methods you need
to call.
Você pode usar casting para dizer ao Godot o tipo que você espera quando você obtém um nó: `` ($ Timer as Timer) ``, `` ($ Player as KinematicBody2D) `` etc. O Godot irá verificar que o tipo funciona e, se funcionar, o número da linha ficará verde à esquerda do editor de script.

Unsafe line (line 7) vs Safe Lines (line 6 and 8)
Nota
Você pode desativar linhas seguras ou alterar suas cores nas configurações do editor.
Defina o tipo de retorno de uma função com a seta ->¶
Para definir o tipo de retorno de uma função, coloque um traço e o símbolo de menor que ->
depois de sua declaração, seguido pelo tipo de retorno:
func _process(delta: float) -> void:
pass
O tipo void
significa que a função não retorna nada. Você pode usar qualquer tipo, como com variáveis:
func hit(damage: float) -> bool:
health_points -= damage
return health_points <= 0
Você também pode usar seus próprios nós como tipos de retorno:
# Inventory.gd
# Adds an item to the inventory and returns it.
func add(reference: Item, amount: int) -> Item:
var item: Item = find_item(reference)
if not item:
item = ItemDatabase.get_instance(reference)
item.amount += amount
return item
Tipada ou dinâmica: Adote um estilo¶
Typed GDScript and dynamic GDScript can coexist in the same project. But I recommend to stick to either style for consistency in your codebase, and for your peers. It's easier for everyone to work together if you follow the same guidelines, and faster to read and understand other people's code.
Typed code takes a little more writing, but you get the benefits we discussed above. Here's an example of the same, empty script, in a dynamic style:
extends Node
func _ready():
pass
func _process(delta):
pass
E com a tipagem estática:
extends Node
func _ready() -> void:
pass
func _process(delta: float) -> void:
pass
As you can see, you can also use types with the engine's virtual
methods. Signal callbacks, like any methods, can also use types. Here's
a body_entered
signal in a dynamic style:
func _on_Area2D_body_entered(body):
pass
E a mesma chamada de retorno, com as dicas de tipo:
func _on_area_entered(area: CollisionObject2D) -> void:
pass
You're free to replace, e.g. the CollisionObject2D
, with your own type,
to cast parameters automatically:
func _on_area_entered(bullet: Bullet) -> void:
if not bullet:
return
take_damage(bullet.damage)
The bullet
variable could hold any CollisionObject2D
here, but
we make sure it is our Bullet
, a node we created for our project. If
it's anything else, like an Area2D
, or any node that doesn't extend
Bullet
, the bullet
variable will be null
.
Sistema de alertas¶
Nota
A documentação sobre o sistema de avisos do GDScript foi movido para GDScript warning system.
Cases where you can't specify types¶
To wrap up this introduction, let's cover a few cases where you can't use type hints. All the examples below will trigger errors.
You can't use Enums as types:
enum MoveDirection {UP, DOWN, LEFT, RIGHT}
var current_direction: MoveDirection
You can't specify the type of individual members in an array. This will give you an error:
var enemies: Array = [$Goblin: Enemy, $Zombie: Enemy]
You can't force the assignment of types in a for
loop, as each
element the for
keyword loops over already has a different type. So you
cannot write:
var names = ["John", "Marta", "Samantha", "Jimmy"]
for name: String in names:
pass
Two scripts can't depend on each other in a cyclic fashion:
# Player.gd
extends Area2D
class_name Player
var rifle: Rifle
# Rifle.gd
extends Area2D
class_name Rifle
var player: Player
Resumo¶
GDScript tipado é uma ferramenta poderosa. Disponível na versão 3.1 do Godot, lhe ajudará a escrever um código mais estruturado, evitando erros comuns, e a criar sistemas escaláveis. No futuro, a tipagem estática também te trará um bom aumento de desempenho graças às futuras otimizações do compilador.