Básicos do GDScript¶
Introdução¶
GDScript é uma linguagem de auto nível, dinâmicamente tipada, usada para criar conteúdo. Utiliza uma sintaxe similar a do Python (blocos são baseados em indentação e muitas palavras-chave são similares). Seu objetivo é ser otimizada para e firmemente integrada ao motor Godot, permitindo grande flexibilidade para a criação e integração de conteúdo.
História¶
Nota
A documentação sobre a história do GDScript foi movida para o Frequently Asked Questions.
Exemplo de GDScript¶
Algumas pessoas conseguem aprender melhor observando a sintaxe, então aqui está um simples exemplo de como o GDScript parece.
# A file is a class!
# Inheritance
extends BaseClass
# (optional) class definition with a custom icon
class_name MyClass, "res://path/to/optional/icon.svg"
# Member variables
var a = 5
var s = "Hello"
var arr = [1, 2, 3]
var dict = {"key": "value", 2: 3}
var typed_var: int
var inferred_type := "String"
# Constants
const ANSWER = 42
const THE_NAME = "Charly"
# Enums
enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALLY}
enum Named {THING_1, THING_2, ANOTHER_THING = -1}
# Built-in vector types
var v2 = Vector2(1, 2)
var v3 = Vector3(1, 2, 3)
# Function
func some_function(param1, param2):
var local_var = 5
if param1 < local_var:
print(param1)
elif param2 > 5:
print(param2)
else:
print("Fail!")
for i in range(20):
print(i)
while param2 != 0:
param2 -= 1
var local_var2 = param1 + 3
return local_var2
# Functions override functions with the same name on the base/parent class.
# If you still want to call them, use '.' (like 'super' in other languages).
func something(p1, p2):
.something(p1, p2)
# Inner class
class Something:
var a = 10
# Constructor
func _init():
print("Constructed!")
var lv = Something.new()
print(lv.a)
Se você possui experiência prévia com linguagens estaticamente tipadas, como C, C++, ou C#, mas nunca utilizou uma linguagem dinamicamente tipada antes, é aconselhado que leia este tutorial: GDScript: Uma introdução às linguagens dinâmicas.
Linguagem¶
A seguir, uma visão geral é dada sobre o GDScript. Detalhes, como quais métodos são disponíveis para arrays ou outros objetos, devem ser vistos nas descrições da classe relacionada.
Identificadores¶
Qualquer String que se restringe a caracteres alfabéticos (a
a z
e A
a Z
), dígitos (0
a 9
) e _
se qualifica como um identificador. Além disso, identificadores não devem começar com um dígito. Identificadores são [i]case-sensitive[/i] (foo
é diferente de FOO
).
Palavras-chave¶
A seguir está a lista de palavras-chaves suportadas pela linguagem. Já que as palavras-chaves são palavras reservadas (código), elas não podem ser usadas como identificadores. Operadores (como in
, not
, and
ou or
) e nomes de tipos embutidos como os listados nas seções seguintes são também palavras reservadas.
Palavras chaves são definidas no tokenizador da GDScript no caso de você querer dar uma olhada nos bastidores.
Palavra-chave | Descrição |
---|---|
if | Veja if/else/elif. |
elif | Veja if/else/elif. |
else | Veja if/else/elif. |
for | Veja for. |
while | Veja while. |
match | Veja match. |
break | Sai da execução do atual laço for ou while . |
continue | Pula imediatamente a próxima iteração do laço for ou while . |
pass | Usado onde uma declaração é requerida sintaticamente, mas a execução do código é indesejada ,por exemplo em funções vazias. |
return | Retorna um valor de uma função. |
class | Defines an inner class. |
class_name | Defines a class name and optional icon for your script. |
extends | Define qual classe estender com a classe atual. |
is | Testa se uma variável extende de uma classe dada, ou é de um certo tipo embutido. |
as | Transmita o valor para um determinado tipo, se possível. |
self | Refere-se a instância atual da classe. |
tool | Executa o script no editor. |
signal | Define um sinal. |
func | Define uma função. |
static | Define uma função estática. Variáveis membro estáticas não são permitidas. |
const | Define uma constante. |
enum | Define um enumerador. |
var | Define uma variável. |
onready | Inicializa uma variável quando o Nó ao qual o script está anexado e os seus filhos fizerem parte da árvore da cena. |
export | Salva a variável junto com o recurso que ela está ligada e a torna visível e modificável no editor. |
setget | Define funções setter e getter para uma variável. |
breakpoint | Ajudante do Editor para debugar pontos de parada. |
preload | Pré-carrega uma classe ou uma variável. Consulte 'Classes como recursos' _. |
conceder | Co-rotina de suporte. Consulte " co-rotinas com o rendimento`_. |
assert | Declara uma condição, erro de logs em caso de falha. Ignorado em compilações de não-depuração. Consulte 'Afirmar a palavra-chave' _. |
remote | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
master | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
fantoche | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
remotesync | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
mastersync | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
puppetsync | Anotação de RPC de redes. Consulte: ref: 'documentos de multijogador de alto nível <doc_high_level_multiplayer>'. |
PI | A constante PI. |
TAU | A constante TAU. |
INF | Constante de infinito. Usada para comparações. |
NAN | Constante de NAN (não um número). Usada para comparações. |
Operadores¶
A seguir, está a lista de operadores suportados e sua precedência.
Operador | Descrição |
x[index] |
Inscrição (prioridade máxima) |
x.attribute |
Referência de atributo |
foo() |
Chamada de função |
is |
Checagem de tipo de instância |
~ |
NÃO Binário |
-x |
Negativo / Negação unária |
* / % |
Multiplicação / Divisão / Resto Esses operadores têm o mesmo comportamento que o C ++. A divisão inteira é truncada em vez de retornar um número fracionário, e o operador% está disponível apenas para ints ("fmod" para floats) |
+ |
Adição / Concatenação de matrizes |
- |
Subtração |
<< >> |
Deslocamento de bits |
& |
E Binário |
^ |
OU EXCLUSIVO Binário |
| |
OU Binário |
< > == != >= <= |
Comparações |
in |
Teste de conteúdo |
! not |
NÃO Booleano |
and && |
E Booleano |
or || |
OU Booleano |
if x else |
if/else Ternário |
as |
Type casting |
= += -= *= /= %= &= |= |
Atribuição (menor prioridade) |
Literais¶
Literal | Tipo |
45 |
Inteiro Base 10 |
0x8f51 |
Inteiro de base 16 (hexadecimal) |
0b101010 |
Inteiro de base 2 (binário) |
3.14 , 58.1e-10 |
Número de ponto flutuante (real) |
"Olá" , "Oi" |
Strings |
"""Olá""" |
String com múltiplas linhas |
@"Nodo/Rotulo" |
NodePath ou StringName |
$NodePath |
Forma abreviada para get_node("NodePath") |
Integers and floats can have their numbers separated with _
to make them more readable.
The following ways to write numbers are all valid:
12_345_678 # Equal to 12345678.
3.141_592_7 # Equal to 3.1415927.
0x8080_0000_ffff # Equal to 0x80800000ffff.
0b11_00_11_00 # Equal to 0b11001100.
Comentários¶
Qualquer coisa desde um #
até o fim da linha é ignorada e é considerada como um comentário.
# This is a comment.
Tipos definidos por padrão¶
Tipos embutidos são alocados em pilha. Eles são passados como valores. Isso significa que uma cópia é criada em cada atribuição ou quando passadas como argumentos para funções. As únicas exceções são Array
s e Dictionaries
, que são passados por referência e portanto são compartilhados. (Matrizes agrupadas como PoolByteArray
ainda são passadas como valores.)
Tipos básicos definidos por padrão¶
Uma variável no GDScript pode ser atribuída a vários tipos definidos por padrão.
null¶
null
é um tipo de dados vazio que não contém informação nenhuma e que não pode ser atribuído nenhum outro valor.
int¶
Abreviação de "inteiro", armazena valores inteiros(positivos e negativos). Ele é armazenado como um valor de 64 bits, equivalente a "int64_t " em C++.
float¶
Armazena números reais, incluindo decimais, usando valores de ponto flutuante. Ele é armazenado como um valor de 64 bits, equivalente a "Double " em C++. Observação: atualmente, estruturas de dados, como Vector2, Vector3 e PoolRealArray armazenam 32 bit de ponto flutuante, ou seja 32 números após a virgula.
String¶
Uma sequência de caracteres no Formato Unicode. Strings podem conter as seguintes sequências de escape:
Escape sequence | Expands to |
\n |
Newline (line feed) |
\t |
Horizontal tab character |
\r |
Carriage return |
\a |
Alert (beep/bell) |
\b |
Backspace |
\f |
Formfeed page break |
\v |
Vertical tab character |
\" |
Double quote |
\' |
Single quote |
\\ |
Backslash |
\uXXXX |
Unicode codepoint XXXX
(hexadecimal, case-insensitive) |
GDScript also supports Formatação de Strings em GDScript.
Tipos básicos de vetor¶
Rect2¶
O tipo 2D Rectangle contém dois campos vetoriais: position
e size
. Contém também um campo end
que é position + size
.
Transform2D¶
Matrix de 3x2 usada para transformações em 2D.
Plane¶
Tipo Plano 3D em formato normalizado que contém um campo vetorial "normal" e uma distância escalar "d".
Quat¶
Quaternion é um tipo de dado utilizado para representar uma rotação 3D. Isto é útil para interporlar rotações.
AABB¶
Caixa delimitadora alinhada por eixo (ou caixa 3D) contém 2 campos vetoriais: position
e size
. Contém também um campo end
que é position + size
.
Tipos definidos por padrão da Engine¶
Color¶
O tipo de dados Color contem campos r
, g
, b
e a
para vermelho, verde, azul e transparência respectivamente. E podem também ser acessados como h
, s
, e v
para matiz, saturação e valor respectivamente.
Tipos contêiner definidos por padrão¶
Array¶
Sequência genérica de tipos de objeto arbitrária, incluindo outras matrizes ou dicionários (veja abaixo). A matriz pode redimensionar dinamicamente. Matrizes são indexados iniciando do índice 0
. Índices negativos contam do final.
var arr = []
arr = [1, 2, 3]
var b = arr[1] # This is 2.
var c = arr[arr.size() - 1] # This is 3.
var d = arr[-1] # Same as the previous line, but shorter.
arr[0] = "Hi!" # Replacing value 1 with "Hi!".
arr.append(4) # Array is now ["Hi!", 2, 3, 4].
Matrizes em GDScript são alocadas linearmente na memória para aumentar sua velocidade. Matrizes muito grandes (mais de dezenas de milhares de elementos) podem, no entanto, causar fragmentação de memória. Se isso for uma preocupação, existem tipos especiais de matriz. Estas aceitam apenas um único tipo de dados. Elas evitam a fragmentação de memória e também usam menos memória, mas são atômicas e tendem a ser mais lentas que as matrizes genéricas. Portanto, elas são recomendadas somente para grandes conjuntos de dados:
- PoolByteArray: Um array de bytes (inteiros com valor de 0 até 255).
- PoolIntArray: Um array de inteiros.
- PoolRealArray: Um array de floats.
- PoolStringArray: Um array de strings.
- PoolVector2Array: Um array de objetos Vector2.
- PoolVector3Array: Um array de objetos Vector3.
- PoolColorArray: Um array de objetos Color.
Dictionary¶
Contêiner associativo que armazena valores referenciados por chaves únicas.
var d = {4: 5, "A key": "A value", 28: [1, 2, 3]}
d["Hi!"] = 0
d = {
22: "value",
"some_key": 2,
"other_key": [2, 3, 4],
"more_key": "Hello"
}
Sintaxe de tabela no estilo Lua também é suportada. O estilo Lua usa =
ao invés de :
e não usa aspas para marcar chaves que são strings (diminuindo a quantidade de escrita). Note, no entanto, que como qualquer identificador GDScript, chaves escritas desta forma não podem começar com dígitos.
var d = {
test22 = "value",
some_key = 2,
other_key = [2, 3, 4],
more_key = "Hello"
}
Para adicionar uma chave a um dicionário existente, acesse isso como uma chave existente e atribua a isso:
var d = {} # Create an empty Dictionary.
d.waiting = 14 # Add String "waiting" as a key and assign the value 14 to it.
d[4] = "hello" # Add integer 4 as a key and assign the String "hello" as its value.
d["Godot"] = 3.01 # Add String "Godot" as a key and assign the value 3.01 to it.
var test = 4
# Prints "hello" by indexing the dictionary with a dynamic key.
# This is not the same as `d.test`. The bracket syntax equivalent to
# `d.test` is `d["test"]`.
print(d[test])
Nota
The bracket syntax can be used to access properties of any Object, not just Dictionaries. Keep in mind it will cause a script error when attempting to index a non-existing property. To avoid this, use the Object.get() and Object.set() methods instead.
Dados¶
Variáveis¶
Variáveis podem existir como membros de classe ou locais em funções. Elas são criadas com a palavra-chave var
e podem, opcionalmente, ser atribuídas com um valor durante a inicialização.
var a # Data type is 'null' by default.
var b = 5
var c = 3.8
var d = b + c # Variables are always initialized in order.
As variáveis podem, opcionalmente, ter uma especificação de tipo. Quando um tipo é especificado, a variável será forçada a ter sempre esse mesmo tipo, e tentar atribuir um valor incompatível gerará um erro.
Os tipos são especificados na declaração da variável usando um símbolo ``: `` (dois-pontos) após o nome da variável, seguido pelo tipo.
var my_vector2: Vector2
var my_node: Node = Sprite.new()
Se a variável for inicializada dentro da declaração, o tipo pode ser inferido, então é possível omitir o nome do tipo:
var my_vector2 := Vector2() # 'my_vector2' is of type 'Vector2'.
var my_node := Sprite.new() # 'my_node' is of type 'Sprite'.
A inferência de tipos só é possível se o valor atribuído tiver um tipo definido, caso contrário, irá gerar um erro.
Tipos válidos são:
- Tipos embutidos (Array, Vector2, int, String, etc.).
- Classes da engine (Node, Resource, Reference, etc.).
- Nomes constantes se eles contiverem um recurso de script (`` MyScript`` se você declarar `` const MyScript = preload ("res: //my_script.gd") ``).
- Outras classes no mesmo script, respeitando o escopo (
InnerClass.NestedClass
se você declarouclassNestedClass
dentro daclassInnerClass
no mesmo escopo). - Classes de script declaradas com a palavra-chave `` class_name``.
Conversão¶
Valores atribuídos a variáveis digitadas devem ter um tipo compatível. Se for necessário forçar um valor a ser de um determinado tipo, em particular para tipos de objetos, você pode usar o operador de conversão as
.
A conversão entre tipos de objetos resulta no mesmo objeto se o valor for do mesmo tipo ou um subtipo do tipo de conversão.
var my_node2D: Node2D
my_node2D = $Sprite as Node2D # Works since Sprite is a subtype of Node2D.
Se o valor não for um subtipo, a operação de conversão resultará em um valor `` null``.
var my_node2D: Node2D
my_node2D = $Button as Node2D # Results in 'null' since a Button is not a subtype of Node2D.
Para tipos internos, eles serão convertidos à força, se possível, caso contrário, o mecanismo gerará um erro.
var my_int: int
my_int = "123" as int # The string can be converted to int.
my_int = Vector2() as int # A Vector2 can't be converted to int, this will cause an error.
Conversão também é útil para ter melhores variáveis de tipo seguro ao interagir com a árvore da cena:
# Will infer the variable to be of type Sprite.
var my_sprite := $Character as Sprite
# Will fail if $AnimPlayer is not an AnimationPlayer, even if it has the method 'play()'.
($AnimPlayer as AnimationPlayer).play("walk")
Constantes¶
Constants are values you cannot change when the game is running.
Their value must be known at compile-time. Using the
const
keyword allows you to give a constant value a name. Trying to assign a
value to a constant after it's declared will give you an error.
We recommend using constants whenever a value is not meant to change.
const A = 5
const B = Vector2(20, 20)
const C = 10 + 20 # Constant expression.
const D = Vector2(20, 30).x # Constant expression: 20.
const E = [1, 2, 3, 4][0] # Constant expression: 1.
const F = sin(20) # 'sin()' can be used in constant expressions.
const G = x + 20 # Invalid; this is not a constant expression!
const H = A + 20 # Constant expression: 25 (`A` is a constant).
Embora o tipo de constantes seja inferido a partir do valor atribuído, também é possível adicionar especificação de tipo explícito:
const A: int = 5
const B: Vector2 = Vector2()
Atribuir um valor de um tipo incompatível gerará um erro.
Nota
Since arrays and dictionaries are passed by reference, constants are "flat". This means that if you declare a constant array or dictionary, it can still be modified afterwards. They can't be reassigned with another value though.
Enumeradores¶
Enumeradores são basicamente alternativas para constantes, e são muito úteis se você quer atribuir inteiros consecutivos para alguma constante.
Se você passar um nome para um enum, ele irá colocar todas as chaves dentro de um dicionário constante com aquele nome.
Importante
A partir do Godot 3.1, chaves em um enum nomeado não são registradas como constantes globais. Elas devem ser acessadas com o prefixo do nome do enum (Name.KEY
); veja no exemplo abaixo.
enum {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT}
# Is the same as:
const TILE_BRICK = 0
const TILE_FLOOR = 1
const TILE_SPIKE = 2
const TILE_TELEPORT = 3
enum State {STATE_IDLE, STATE_JUMP = 5, STATE_SHOOT}
# Is the same as:
const State = {STATE_IDLE = 0, STATE_JUMP = 5, STATE_SHOOT = 6}
# Access values with State.STATE_IDLE, etc.
Funções¶
Funções sempre pertencem a class. A prioridade de escopo para a procura de variáveis é: local → membro da classe → global. A variável self
é sempre disponível e é fornecida como uma opção para acessar membros da classe, mas não é sempre necessária (e , diferente do Python, não deve ser enviada como o primeiro argumento de uma função).
func my_function(a, b):
print(a)
print(b)
return a + b # Return is optional; without it 'null' is returned.
Uma função pode retornar
em qualquer ponto. O valor padrão de retorno é null
.
Funções também podem ter especificação de tipo para os argumentos e para o valor de retorno. Tipos de argumentos podem ser adicionados de forma semelhante às variáveis:
func my_function(a: int, b: String):
pass
Se um argumento de função tiver um valor padrão, é possível inferir o tipo:
func my_function(int_arg := 42, String_arg := "string"):
pass
O tipo de retorno da função pode ser especificado após a lista de argumentos usando o token de seta (->
):
func my_int_function() -> int:
return 0
Funções que possuem um tipo de retorno devem retornar um valor adequado. Definir o tipo como void
significa que a função não retorna nada. As funções void podem retornar cedo com a palavra-chave return
, mas não podem retornar nenhum valor.
void_function() -> void:
return # Can't return a value
Nota
Funções não void devem sempre retornar um valor, então se seu código possui instruções de ramificação (como um construtor if
/ else
), todos os caminhos possíveis devem ter um retorno. Por exemplo, se você tiver um return
dentro de um bloco if
, mas não depois, o editor irá gerar um erro, porque se o bloco não for executado, a função não terá um valor válido para retornar.
Referenciando funções¶
Ao contrário do Python, funções não são objetos de primeira-classe em GDScript. Isso significa que elas não podem ser armazenadas em variáveis, passadas como argumento para outras funções ou retornadas de outras funções. Essas limitações são por motivos de performance.
Para referenciar uma função pelo nome durante o tempo de execução, (ex: para armazenar em uma variável, ou passar para uma outra função como um argumento) você precisa usar os auxiliares call
ou funcref
:
# Call a function by name in one step.
my_node.call("my_function", args)
# Store a function reference.
var my_func = funcref(my_node, "my_function")
# Call stored function reference.
my_func.call_func(args)
Funções estáticas¶
Uma função pode ser declarada como estática. Quando uma função é estática, ela não possui acesso as variáveis de instância ou ao self
. Isso é útil principalmente para a criação de bibliotecas de funções auxiliares:
static func sum2(a, b):
return a + b
Expressões e fluxo de controle¶
Expressões são padrão e podem ser atribuições, chamadas de função, estruturas de controle, etc (veja abaixo). ;
como um separador de expressões é inteiramente opcional.
if/else/elif¶
Condições simples são criadas usando a sintaxe if
/else
/elif
. Parênteses ao redor de condições são permitidos, mas não obrigatórios. Dada a natureza dos recuos baseados em tabs, elif
pode ser usado ao invés de else
/if
para manter o nível de recuo.
if [expression]:
statement(s)
elif [expression]:
statement(s)
else:
statement(s)
Expressões curtas podem ser escritas na mesma linha da condição:
if 1 + 1 == 2: return 2 + 2
else:
var x = 3 + 3
return x
Às vezes, você pode querer atribuir um valor inicial diferente baseado em uma expressão booleana. Nesse caso, expressões do tipo if-ternário são úteis:
var x = [value] if [expression] else [value]
y += 3 if y < 10 else -1
while¶
Laços simples são criados utilizando a sintaxe while
. Laços podem ser interrompidos utilizando break
ou continuados utilizando continue
:
while [expression]:
statement(s)
for¶
To iterate through a range, such as an array or table, a for loop is used. When iterating over an array, the current array element is stored in the loop variable. When iterating over a dictionary, the key is stored in the loop variable.
for x in [5, 7, 11]:
statement # Loop iterates 3 times with 'x' as 5, then 7 and finally 11.
var dict = {"a": 0, "b": 1, "c": 2}
for i in dict:
print(dict[i]) # Prints 0, then 1, then 2.
for i in range(3):
statement # Similar to [0, 1, 2] but does not allocate an array.
for i in range(1, 3):
statement # Similar to [1, 2] but does not allocate an array.
for i in range(2, 8, 2):
statement # Similar to [2, 4, 6] but does not allocate an array.
for c in "Hello":
print(c) # Iterate through all characters in a String, print every letter on new line.
for i in 3:
statement # Similar to range(3)
for i in 2.2:
statement # Similar to range(ceil(2.2))
match¶
Uma expressão match
é usada para ramificar a execução de um programa. É equivalente à expressão switch
encontrada em muitas outras linguagens de programação, mas oferece algumas funcionalidades adicionais.
Sintaxe básica:
match [expression]:
[pattern](s):
[block]
[pattern](s):
[block]
[pattern](s):
[block]
Curso rápido para pessoas familiarizadas com expressões switch:
- Substitua
switch
pormatch
. - Remova
case
. - Remova todos os
break
s. Se você não quer interromper (break
) por padrão, você pode usarcontinue
para contornar. - Troque
default
por um único sublinhado.
Controle de fluxo:
The patterns are matched from top to bottom.
If a pattern matches, the first corresponding block will be executed. After that, the execution continues below the match
statement.
You can use continue
to stop execution in the current block and check for an additional match in the patterns below it.
Há 6 tipos de padrões:
- Padrão de constante
Constantes primitivas, como números e textos:
match x: 1: print("We are number one!") 2: print("Two are better than one!") "test": print("Oh snap! It's a string!")
- Padrão de variável
Compara o conteúdo de uma variável/enumeração:
match typeof(x): TYPE_REAL: print("float") TYPE_STRING: print("text") TYPE_ARRAY: print("array")
- Padrão coringa
Este padrão compara/coincide com tudo. É escrito com uma única sublinha _ .
Pode ser usado como equivalente ao
default
de uma expressãoswitch
em outras linguagens:match x: 1: print("It's one!") 2: print("It's one times two!") _: print("It's not 1 or 2. I don't care to be honest.")
- Padrão de ligação
Um padrão de ligação introduz uma nova variável. Como o padrão coringa, ele coincide com tudo – e ainda dá a esse valor um nome. É útil especialmente para padrões de matriz e de dicionário.
match x: 1: print("It's one!") 2: print("It's one times two!") var new_var: print("It's not 1 or 2, it's ", new_var)
- Padrão de matriz
Compara com um matriz. Cada elemento do padrão é um padrão por si só, para que você possa aninhá-los.
O comprimento da matriz é testado primeiro, ele tem que ter o mesmo tamanho do padrão, senão o padrão não coincide.
Matriz sem término: Uma matriz pode ser maior que o padrão deixando como último subpadrão
..
.Todo subpadrão precisa ser separado por vírgulas.
match x: []: print("Empty array") [1, 3, "test", null]: print("Very specific array") [var start, _, "test"]: print("First element is ", start, ", and the last is \"test\"") [42, ..]: print("Open ended array")
- Padrão de dicionário
Funciona da mesma forma que o padrão de array. Toda chave precisa ser um padrão constante.
O tamanho do dicionário é testado primeiro, ele tem que ser o mesmo tamanho do padrão, senão o padrão não coincide.
Dicionário sem término: Um dicionário pode ser maior que o padrão deixando como último subpadrão
..
.Qualquer subpadrão precisa ser separado por vírgulas.
Se você não especificar um valor, só a existência da chave é conferida.
Um padrão de valor é separado do padrão de chave com
:
.match x: {}: print("Empty dict") {"name": "Dennis"}: print("The name is Dennis") {"name": "Dennis", "age": var age}: print("Dennis is ", age, " years old.") {"name", "age"}: print("Has a name and an age, but it's not Dennis :(") {"key": "godotisawesome", ..}: print("I only checked for one entry and ignored the rest")
- Multipadrões
Você pode especificar múltiplos padrões separando-os por uma vírgula. Esses padrões não são permitidos de ter quaisquer ligações.
match x: 1, 2, 3: print("It's 1 - 3") "Sword", "Splash potion", "Fist": print("Yep, you've taken damage")
Classes¶
Por padrão, todos os arquivos de scripts são classes sem nome. Neste caso, você só irá poder os referenciar usando o caminho do arquivo, usando tanto um caminho relativo como um absoluto. Por exemplo, se você nomear um arquivo de script character.gd
:
# Inherit from 'Character.gd'.
extends "res://path/to/character.gd"
# Load character.gd and create a new node instance from it.
var Character = load("res://path/to/character.gd")
var character_node = Character.new()
No entanto, você pode dar um nome a sua classe para registrá-la como um novo tipo no editor do Godot. Para isso, você pode usar a palavra chave class_name
. Você pode adicionar uma vírgula opcional seguida de um caminho para uma imagem, para utilizar como ícone. Sua classe, aparecerá, então, com seu novo ícone no editor:
# Item.gd
extends Node
class_name Item, "res://interface/icons/item.png"

Aqui está um exemplo de um arquivo de classe:
# Saved as a file named 'character.gd'.
class_name Character
var health = 5
func print_health():
print(health)
func print_this_script_three_times():
print(get_script())
print(ResourceLoader.load("res://character.gd"))
print(Character)
Nota
A sintaxe da classe do Godot é compacta: ela só pode conter variáveis membros ou funções. Você pode utilizar funções estáticas, mas não membros variáveis não-estáticas. Do mesmo modo, o motor inicializará variáveis toda vez que você criar uma instância, e isso inclui arrays e dicionários. Isso serve para segurança de threads, já que scripts podem ser inicializados em threads separados sem que o usuário saiba.
Herança¶
Uma classe (salva como um arquivo) pode herdar de:
- Uma classe global.
- Um outro arquivo de classe.
- Uma classe interna dentro de outro arquivo de classe.
Herança múltipla não é permitida.
Herança usa a palavra-chave extends
:
# Inherit/extend a globally available class.
extends SomeClass
# Inherit/extend a named class file.
extends "somefile.gd"
# Inherit/extend an inner class in another file.
extends "somefile.gd".SomeInnerClass
Para verificar se uma certa instância herda de uma certa classe, a palavra-chave is
(é) pode ser usada:
# Cache the enemy class.
const Enemy = preload("enemy.gd")
# [...]
# Use 'is' to check inheritance.
if entity is Enemy:
entity.apply_damage()
Para chamar uma função em uma classe base (ex: um extend
-ido em sua classe atual), insira um .
no início do nome da função:
.base_func(args)
Isso é especialmente útil porque funções em classes extendidas substituem as funções com o mesmo nome em suas classes de base. Então se você ainda quiser chamá-los, você pode usar .
no início (como a palavra-chave super
em outras linguagens):
func some_func(x):
.some_func(x) # Calls the same function on the parent class.
Nota
Funções padrão como _init
, e a maioria das notificações como _enter_tree
, _exit_tree
, _process
, _physics_process
, etc. são chamadas em todas as classes base automaticamente. Não é necessário chamá-las explicitamente quando estiver sobrecarregando-as.
Construtor de Classe¶
O construtor de classe, chamada ao criar uma instância da classe, é chamado de _init
. Como mencionado anteriormente, os construtores de classes-pai são chamados automaticamente ao herdar uma classe. Então não costuma haver necessidade de chamar ._init()
explicitamente.
Ao contrário da chamada de uma função normal, como no exemplo acima com .some_func
, se o construtor da classe herdada tiver argumentos, serão passados da seguinte forma:
func _init(args).(parent_args):
pass
Isso é melhor explicado através de exemplos. Suponha que tenhamos tal cenário:
# State.gd (inherited class)
var entity = null
var message = null
func _init(e=null):
entity = e
func enter(m):
message = m
# Idle.gd (inheriting class)
extends "State.gd"
func _init(e=null, m=null).(e):
# Do something with 'e'.
message = m
Têm algumas coisas para manter em mente aqui:
Se a classe herdada (
State.gd
) definir um construtor_init
que precisa de argumentos (e
nesse caso) então a classe que herda (Idle.gd
) precisa definir um_init
também, e passar os parâmetros apropriados para o_init
deState.gd
.Idle.gd
pode ter um número diferente de argumentos que a classe baseState.gd
.No exemplo acima,
e
passado para o construtor deState.gd
é o mesmoe
que foi passado para oIdle.gd
.Se o construtor
_init
deIdle.gd
não precisa de argumentos, ele ainda precisa passar algum valor para a classe baseState.gd
, mesmo que ele não faça nada. Isso nos leva ao fato que você pode passar valores literais ao construtor também, não só variáveis. ex:# Idle.gd func _init().(5): pass
Classes internas¶
Um arquivo de classe pode conter classes internas. Elas são definidas usando a palavra-chave class
. Instâncias podem ser criadas usando a função NomeDaClasse.new()
.
# Inside a class file.
# An inner class in this class file.
class SomeInnerClass:
var a = 5
func print_value_of_a():
print(a)
# This is the constructor of the class file's main class.
func _init():
var c = SomeInnerClass.new()
c.print_value_of_a()
Classes como recursos¶
Classes armazenadas em arquivos são tratadas como resources. Elas podem ser carregadas do disco para acessá-las em outras classes. Isso é feito ou pela função load
ou pela preload
(veja abaixo). Instâncias de uma classe carregada como recurso são feitas chamando a função new
no objeto da classe:
# Load the class resource when calling load().
var my_class = load("myclass.gd")
# Preload the class only once at compile time.
const MyClass = preload("myclass.gd")
func _init():
var a = MyClass.new()
a.some_function()
Exportações¶
Nota
A documentação sobre a exportação foi movida para Exports no GDScript.
Setters (setadores) /getters (coletores)¶
É muito comum ser útil saber quando uma variável membro de classe se altera por qualquer que seja o motivo. Também pode ser desejado encapsular seu acesso de alguma forma.
Para isso, a GDScript provê uma sintaxe de setter/getter usando a palavra-chave setget
, usada diretamente depois de uma definição de variável:
var variable = value setget setterfunc, getterfunc
Sempre que o valor da variável
for modificado por uma fonte externa (não por uso local na classe), a função setter (setterfunc
acima) será chamada. Isso acontece antes do valor ser mudado. O setter precisa decidir o que fazer com o novo valor. Do mesmo modo, quando variable
é acessado, a função getter (getterfunc
acima) precisa retornar (return
) o valor desejado. A seguir um exemplo:
var my_var setget my_var_set, my_var_get
func my_var_set(new_value):
my_var = new_value
func my_var_get():
return my_var # Getter must return a value.
Qualquer uma das funções setter ou getter podem ser omitidas:
# Only a setter.
var my_var = 5 setget my_var_set
# Only a getter (note the comma).
var my_var = 5 setget ,my_var_get
Setters e getters são úteis especialmente ao exportar variáveis ao editor em scripts de ferramentas ou plugins, para validação de entrada.
Como dito, acesso local não irá iniciar o setter e getter. Aqui temos uma ilustração disso:
func _init():
# Does not trigger setter/getter.
my_integer = 5
print(my_integer)
# Does trigger setter/getter.
self.my_integer = 5
print(self.my_integer)
Modo de Ferramenta¶
Scripts, por padrão, não executam dentro do editor e apenas as propriedades exportadas podem ser modificadas. Em alguns casos, é desejável que eles rodem dentro do editor (enquanto eles não executem código do jogo ou evitem manualmente de fazer isso). Para isso, a palavra tool
existe e deve ser colocada no topo do arquivo:
tool
extends Button
func _ready():
print("Hello")
Veja Running code in the editor para mais informações.
Aviso
Seja cauteloso ao liberar nós com queue_free()
ou free()
em um script de ferramenta (especialmente o próprio dono do script). Como os scripts de ferramentas executam o seu código no editor, o seu uso indevido pode causar falhas no editor.
Gerenciamento de memória¶
If a class inherits from Reference, then instances will be
freed when no longer in use. No garbage collector exists, just
reference counting. By default, all classes that don't define
inheritance extend Reference. If this is not desired, then a class
must inherit Object manually and must call instance.free()
. To
avoid reference cycles that can't be freed, a weakref
function is
provided for creating weak references.
Alternativamente, quando não estiver usando referências, o `` is_instance_valid (instance) `` pode ser usado para verificar se um objeto foi liberado.
Sinais¶
Sinais são um modo de enviar mensagens de um objeto para que outros objetos possam reagir. Crie sinais customizados para uma classe usando a palavra-chave signal
.
extends Node
# A signal named health_depleted.
signal health_depleted
Nota
Sinais são um mecanismo de Callback. Eles também preenchem o papel de observadores, um padrão de programação comum. Para mais informações, leia o tutorial Observer tutorial no ebook Game Programming Patterns.
Esses sinais podem ser conectados a métodos da mesma forma com que você conecta sinais embutidos de nós como Button ou RigidBody.
No exemplo abaixo, conectamos o sinal health_depleted
de um nó Character
a um nó Game
. Quando o nó Character
emite o sinal, a função _on_Character_health_depleted
é chamada no nó Game
:
# Game.gd
func _ready():
var character_node = get_node('Character')
character_node.connect("health_depleted", self, "_on_Character_health_depleted")
func _on_Character_health_depleted():
get_tree().reload_current_scene()
Você pode emitir quantos argumentos desejar com um sinal.
Aqui está um exemplo em que isso é útil. Digamos que queremos que uma barra de vida na tela reaja às mudanças de saúde com uma animação, mas queremos manter a interface do usuário separada do player em nossa árvore de cenas.
Em nosso script `` Character.gd``, definimos um sinal `` health_changed`` e o emitimos com: ref: Object.emit_signal () <class_Object_method_emit_signal> e no nó `` Game`` acima na árvore de cenas, nós a conectamos à `` Lifebar`` usando o método: ref: Object.connect () <class_Object_method_connect>
# Character.gd
...
signal health_changed
func take_damage(amount):
var old_health = health
health -= amount
# We emit the health_changed signal every time the
# character takes damage.
emit_signal("health_changed", old_health, health)
...
# Lifebar.gd
# Here, we define a function to use as a callback when the
# character's health_changed signal is emitted.
...
func _on_Character_health_changed(old_value, new_value):
if old_value > new_value:
progress_bar.modulate = Color.red
else:
progress_bar.modulate = Color.green
# Imagine that `animate` is a user-defined function that animates the
# bar filling up or emptying itself.
progress_bar.animate(old_value, new_value)
...
Nota
Para usar sinais, sua classe precisa estender a classe do``Object`` ou alguma classe como``Node``, KinematicBody
, Control
...
No nó `` Game``, obtemos os nós `` Character`` e `` Lifebar``, em seguida, conectamos o personagem, que emite o sinal ao receptor`` Lifebar`` nesse caso.
# Game.gd
func _ready():
var character_node = get_node('Character')
var lifebar_node = get_node('UserInterface/Lifebar')
character_node.connect("health_changed", lifebar_node, "_on_Character_health_changed")
Isso permite que a Lifebar
reaja às alterações de saúde sem acoplá-la ao nó `` Character``.
Você pode escrever nomes de argumento opcionais entre parênteses após a definição do sinal:
# Defining a signal that forwards two arguments.
signal health_changed(old_value, new_value)
Estes argumentos aparecem na aba Nó do editor, e o Godot pode usá-los para criar funções para você. Entretanto, você ainda pode emitir qualquer número de argumento quando você emite sinais; é você quem tem que emitir os valores corretos.

GDScript pode passar uma matriz de argumentos a conexões entre um sinal e um método. Quando o sinal é emitido, chamando o método conectado, os argumentos são dados ao método. Esses argumentos são específicos a cada conexão, e os valores ficarão iguais.
Você pode usar essa matriz de valores para adicionar informações extras constantes à conexão, se o próprio sinal emitido não der acesso a todos os dados necessários.
Com base no exemplo acima, vamos dizer que queremos exibir um log dos danos recebidos por cada personagem na tela, como Player1 levou 22 de dano.
. O sinal health_changed
não fornece o nome do personagem que levou dano. Então quando conectamos o sinal ao console in-game, podemos adicionar o nome do personagem no argumento da matriz de ligações:
# Game.gd
func _ready():
var character_node = get_node('Character')
var battle_log_node = get_node('UserInterface/BattleLog')
character_node.connect("health_changed", battle_log_node, "_on_Character_health_changed", [character_node.name])
Nosso nó ``BattleLog `` recebe cada elemento na matriz de vínculos como um argumento extra:
# BattleLog.gd
func _on_Character_health_changed(old_value, new_value, character_name):
if not new_value <= old_value:
return
var damage = old_value - new_value
label.text += character_name + " took " + str(damage) + " damage."
Corrotinas com yield¶
GDScript oferece suporte para corrotinas através do comando embutido yield. Chamar yield()
irá sair imediatamente da função atual, com o estado atual congelado desta mesma função como valor de retorno. Chamar resume()
neste objeto resultante irá continuar a execução da função original do ponto que parou e retornar o que quer que a função retorne. Assim que retomada a execução da função suspensa, o objeto de estado se torna inválido. Aqui está um exemplo:
func my_func():
print("Hello")
yield()
print("world")
func _ready():
var y = my_func()
# Function state saved in 'y'.
print("my dear")
y.resume()
# 'y' resumed and is now an invalid state.
Imprimirá:
Hello
my dear
world
Também é possível passar valores entre yield()
e resume()
, por exemplo:
func my_func():
print("Hello")
print(yield())
return "cheers!"
func _ready():
var y = my_func()
# Function state saved in 'y'.
print(y.resume("world"))
# 'y' resumed and is now an invalid state.
Imprimirá:
Hello
world
cheers!
Lembre-se de salvar o estado da nova função, ao utilizar múltiplos yield
s:
func co_func():
for i in range(1, 5):
print("Turn %d" % i)
yield();
func _ready():
var co = co_func();
while co is GDScriptFunctionState && co.is_valid():
co = co.resume();
Corrotinas e sinais¶
O verdadeiro poder de utilizar yield
é quando combinado com sinais. yield
pode aceitar até dois parâmetros, um objeto e um sinal. Quando o sinal é recebido, a execução irá recomeçar. Abaixo temos alguns exemplos:
# Resume execution the next frame.
yield(get_tree(), "idle_frame")
# Resume execution when animation is done playing.
yield(get_node("AnimationPlayer"), "animation_finished")
# Wait 5 seconds, then resume execution.
yield(get_tree().create_timer(5.0), "timeout")
As próprias corrotinas usam o sinal `` completed`` quando fazem a transição para um estado inválido, por exemplo:
func my_func():
yield(button_func(), "completed")
print("All buttons were pressed, hurray!")
func button_func():
yield($Button0, "pressed")
yield($Button1, "pressed")
`` my_func`` somente continuará a execução assim que ambos os botões forem pressionados.
You can also get the signal's argument once it's emitted by an object:
# Wait for when any node is added to the scene tree.
var node = yield(get_tree(), "node_added")
If there is more than one argument, yield
returns an array containing
the arguments:
signal done(input, processed)
func process_input(input):
print("Processing initialized")
yield(get_tree(), "idle_frame")
print("Waiting")
yield(get_tree(), "idle_frame")
emit_signal(input, "Processed " + input)
func _ready():
process_input("Test") # Prints: Processing initialized
var data = yield(self, "done") # Prints: waiting
print(data[1]) # Prints: Processed Test
If you're unsure whether a function may yield or not, or whether it may yield
multiple times, you can yield to the completed
signal conditionally:
func generate():
var result = rand_range(-1.0, 1.0)
if result < 0.0:
yield(get_tree(), "idle_frame")
return result
func make():
var result = generate()
if result is GDScriptFunctionState: # Still working.
result = yield(result, "completed")
return result
This ensures that the function returns whatever it was supposed to return
regardless of whether coroutines were used internally. Note that using
while
would be redundant here as the completed
signal is only emitted
when the function didn't yield anymore.
Palavra-chave Onready¶
Ao usar nós, é comum desejar manter referências a partes da cena em uma variável. Como as cenas só podem ser configuradas ao entrar na árvore da cena ativa, os subnós só podem ser obtidos quando uma chamada para Node._ready()
é feita.
var my_label
func _ready():
my_label = get_node("MyLabel")
Isto pode ficar meio confuso, especialmente com muitos nós e referências externas. Para isso, GDScript tem a palavra-chave onready
, que atrasa a inicialização da variável de um membro até que _ready()
seja chamado. Ela pode substituir o código acima por uma única linha:
onready var my_label = get_node("MyLabel")
Palavra-chave assert¶
A palavra-chave assert
pode ser usada para checar detalhes de depuração de builds. Essas asserções são ignoradas em compilações sem depuração. Isso significa que a expressão passada como argumento não vai ser compilada no projeto final. Por esse motivo, elas ** não ** devem conter expressões que sejam importantes para o código funcionar. Caso contrário, o comportamento do script variará dependendo se está compilando em modo depuração ou não.
# Check that 'i' is 0. If 'i' is not 0, an assertion error will occur.
assert(i == 0)
Se ocorrer um erro de asserção enquanto estiver no modo de edição, o projeto sera pausado.