Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Auswertung von Ausdrücken

Godot bietet eine Klasse Expression, die Sie zur Auswertung von Ausdrücken verwenden können.

Ein Ausdruck kann sein:

  • Ein mathematischer Ausdruck wie (2 + 4) * 16/4,0.

  • Ein Built-in-Methodenaufruf wie deg_to_rad(90).

  • Ein Methodenaufruf in einem benutzerdefinierten Skript wie update_health(), wenn base_instance beim Aufruf von Expression.execute() auf einen anderen Wert als null gesetzt wird.

Bemerkung

Die Expression-Klasse ist unabhängig von GDScript. Sie ist auch dann verfügbar, wenn Sie Godot mit deaktiviertem GDScript-Modul kompilieren.

Grundlegende Verwendung

Um einen mathematischen Ausdruck auszuwerten, verwenden Sie:

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

Folgende Operatoren sind verfügbar:

Operator

Anmerkungen

Addition +

Kann auch zur Verkettung von Strings und Arrays verwendet werden: - "Hallo" + " Welt" = Hallo Welt - [1, 2] + [3, 4] = [1, 2, 3, 4]

Subtraktion (-)

Multiplikation (*)

Division (/)

Führt eine Integer-Division durch, wenn beide Operanden Integer sind. Wenn mindestens einer der beiden Operanden eine Float-Zahl ist, wird ein Float-Wert zurückgegeben.

Modulo (%)

Gibt den Rest einer Integer-Division zurück.

Leerzeichen um Operatoren sind optional. Denken Sie auch daran, dass die übliche Reihenfolge der Operationen gilt. Verwenden Sie Klammern, um die Reihenfolge der Operationen bei Bedarf außer Kraft zu setzen.

Alle in Godot unterstützten Variantentypen können verwendet werden: Integer, Floats, Strings, Arrays, Dictionarys, Farben, Vektoren, …

Arrays und Dictionarys können wie in GDScript indiziert werden:

# 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

Übergabe von Variablen an einen Ausdruck

Sie können Variablen an einen Ausdruck übergeben. Diese Variablen werden dann im "Kontext" des Ausdrucks verfügbar und werden bei der Verwendung im Ausdruck ersetzt:

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

Sowohl die Variablennamen als auch die Variablenwerte müssen als Array angegeben werden, auch wenn Sie nur eine Variable definieren. Außerdem wird bei Variablennamen auf Groß- und Kleinschreibung geachtet.

Festlegen einer Basisinstanz für den Ausdruck

Standardmäßig hat ein Ausdruck eine Basisinstanz von null. Das bedeutet, dass dem Ausdruck keine Basisinstanz zugeordnet ist.

Wenn Sie Ausdruck.execute() aufrufen, können Sie den Wert des Parameters base_instance auf eine bestimmte Objektinstanz wie self, eine andere Skriptinstanz oder sogar ein Singleton: setzen:

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

Das Assoziieren einer Basisinstanz ermöglicht Folgendes:

  • Referenzieren der Instanz-Konstanten (const) in dem Ausdruck.

  • Verweise auf die Instanz-Membervariablen (var) im Ausdruck.

  • Aufruf von Methoden, die in der Instanz definiert sind, und Verwendung ihrer Rückgabewerte in dem Ausdruck.

Warnung

Wenn Sie eine Basisinstanz auf einen anderen Wert als null setzen, können Sie auf Konstanten und Membervariablen verweisen und alle Methoden aufrufen, die in dem mit der Instanz verbundenen Skript definiert sind. Wenn Sie Nutzern erlauben, Ausdrücke einzugeben, kann dies zu Betrug in Ihrem Spiel führen oder sogar zu Sicherheitslücken, wenn Sie beliebigen Clients erlauben, Ausdrücke auf den Geräten anderer Spieler auszuführen.

Beispiel-Skript

Das folgende Skript zeigt, was die Klasse Expression kann:

const DAYS_IN_YEAR = 365
var script_member_variable = 1000


func _ready():
    # 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

Die Ausgabe des Skripts lautet:

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

Built-in-Funktionen

Alle Methoden im Global Scope sind in der Klasse Expression verfügbar, auch wenn keine Basisinstanz an den Ausdruck gebunden ist. Es sind die gleichen Parameter und Rückgabetypen verfügbar.

Im Gegensatz zu GDScript sind Parameter jedoch immer erforderlich, auch wenn sie in der Klassenreferenz als optional angegeben sind. Im Gegensatz dazu gilt diese Einschränkung für Argumente nicht für benutzerdefinierte Funktionen, wenn Sie eine Basisinstanz an den Ausdruck binden.