Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Avaliando as expressões

O Godot fornece uma classe Expression que você pode usar para avaliar expressões.

Uma expressão pode ser:

  • Uma expressão matemática como (2 + 4) * 16/4.0.

  • Uma expressão booleana como true && false.

  • Uma chamada de método nativo como deg_to_rad(90).

  • Uma chamada de método em um script fornecido pelo usuário como update_health(), se base_instance estiver configurado com um valor diferente de null ao chamar Expression.execute().

Nota

A classe Expression é independente do GDScript. Ela está disponível mesmo se você compilar o Godot com o módulo GDScript desativado.

Uso básico

Para avaliar uma expressão matemática, use:

var expression = Expression.new()
expression.parse("20 + 10*2 - 5/2.0")
var result = expression.execute()
print(result)  # 37.5

Os seguintes operadores estão disponíveis:

Operador

Notas

Addition (+)

Também pode ser usado para concatenar strings e arrays: - "hello" + " world" = hello world - [1, 2] + [3, 4] = [1, 2, 3, 4]

Subtração (-)

Multiplicação (*)

Divisão (/)

Realiza uma divisão inteira se ambos os operandos forem inteiros. Se pelo menos um deles for um número de ponto flutuante, retorna um valor de ponto flutuante.

Resto (%)

Retorna o resto de uma divisão inteira (módulo). O resultado sempre terá o sinal do dividendo.

Conjunção (&&)

Retorna o resultado de um AND booleano.

Disjunção (||)

Retorna o resultado de um OR booleano.

Negação (!)

Retorna o resultado de um NOT booleano.

Espaços ao redor dos operadores são opcionais. Além disso, lembre-se de que a ordem das operações usual se aplica. Use parênteses para anular a ordem das operações se necessário.

Todos os tipos de Variant suportados no Godot podem ser usados: inteiros, números de ponto flutuante, strings, arrays, dicionários, cores, vetores, …

Arrays e dicionários podem ser indexados como no GDScript:

# Returns 1.
[1, 2][0]

# Returns 3. Negative indices can be used to count from the end of the array.
[1, 3][-1]

# Returns "green".
{"favorite_color": "green"}["favorite_color"]

# All 3 lines below return 7.0 (Vector3 is floating-point).
Vector3(5, 6, 7)[2]
Vector3(5, 6, 7)["z"]
Vector3(5, 6, 7).z

Passando variáveis para uma expressão

Você pode passar variáveis para uma expressão. Essas variáveis ficarão disponíveis no "contexto" da expressão e serão substituídas quando usadas na expressão:

var expression = Expression.new()
# Define the variable names first in the second parameter of `parse()`.
# In this example, we use `x` for the variable name.
expression.parse("20 + 2 * x", ["x"])
# Then define the variable values in the first parameter of `execute()`.
# Here, `x` is assigned the integer value 5.
var result = expression.execute([5])
print(result)  # 30

Tanto os nomes das variáveis quanto os valores das variáveis devem ser especificados como um array, mesmo se você definir apenas uma variável. Além disso, os nomes das variáveis são case-sensitive.

Definindo uma instância base para a expressão

Por padrão, uma expressão tem uma instância base de null. Isso significa que a expressão não possui nenhuma instância base associada a ela.

Ao chamar Expression.execute(), você pode definir o valor do parâmetro base_instance para uma instância de objeto específica, como self, outra instância de script ou até mesmo um singleton:

func double(number):
    return number * 2


func _ready():
    var expression = Expression.new()
    expression.parse("double(10)")

    # This won't work since we're not passing the current script as the base instance.
    var result = expression.execute([], null)
    print(result)  # null

    # This will work since we're passing the current script (i.e. self)
    # as the base instance.
    result = expression.execute([], self)
    print(result)  # 20

Associar uma instância base permite fazer o seguinte:

  • Referenciar as constantes da instância (const) na expressão.

  • Referenciar as variáveis de membro da instância (var) na expressão.

  • Chamar métodos definidos na instância e usar seus valores de retorno na expressão.

Aviso

Definir uma instância base para um valor diferente de null permite referenciar constantes, variáveis de membro e chamar todos os métodos definidos no script anexado à instância. Permitir que os usuários insiram expressões pode permitir trapaças no seu jogo, ou pode até introduzir vulnerabilidades de segurança se você permitir que clientes arbitrários executem expressões nos dispositivos de outros jogadores.

Exemplo de script

O script abaixo demonstra do que a classe Expression é capaz:

const DAYS_IN_YEAR = 365
var script_member_variable = 1000


func _ready():
    # Constant boolean expression.
    evaluate("true && false")
    # Boolean expression with variables.
    evaluate("!(a && b)", ["a", "b"], [true, false])

    # Constant mathexpression.
    evaluate("2 + 2")
    # Math expression with variables.
    evaluate("x + y", ["x", "y"], [60, 100])

    # Call built-in method (built-in math function call).
    evaluate("deg_to_rad(90)")

    # Call user method (defined in the script).
    # We can do this because the expression execution is bound to `self`
    # in the `evaluate()` method.
    # Since this user method returns a value, we can use it in math expressions.
    evaluate("call_me() + DAYS_IN_YEAR + script_member_variable")
    evaluate("call_me(42)")
    evaluate("call_me('some string')")


func evaluate(command, variable_names = [], variable_values = []) -> void:
    var expression = Expression.new()
    var error = expression.parse(command, variable_names)
    if error != OK:
        push_error(expression.get_error_text())
        return

    var result = expression.execute(variable_values, self)

    if not expression.has_execute_failed():
        print(str(result))


func call_me(argument = null):
    print("\nYou called 'call_me()' in the expression text.")
    if argument:
        print("Argument passed: %s" % argument)

    # The method's return value is also the expression's return value.
    return 0

A saída do script será:

false
true
4
160
1.5707963267949

You called 'call_me()' in the expression text.
1365

You called 'call_me()' in the expression text.
Argument passed: 42
0

You called 'call_me()' in the expression text.
Argument passed: some string
0

Funções embutidas

Todos os métodos no Global Scope estão disponíveis na classe Expression, mesmo se nenhuma instância base estiver vinculada à expressão. Os mesmos parâmetros e tipos de retorno estão disponíveis.

No entanto, diferentemente do GDScript, os parâmetros são sempre obrigatórios, mesmo que estejam especificados como opcionais na referência da classe. Em contrapartida, essa restrição nos argumentos não se aplica a funções criadas pelo usuário quando você vincula uma instância base à expressão.