Up to date

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

Bisect 迴歸

Godot 提供了 Expression 類,可以用來對運算式進行估值。

運算式節點可以:

  • 類似 (2 + 4) * 16/4.0 的數學運算式。

  • 類似 deg2rad(90) 的內建方法呼叫。

  • 呼叫 Expression.execute() 時如果 base_instancenull,那麼呼叫使用者提供腳本的方法,比如 update_health()

備註

Expression 類是獨立於 GDScript 的。即便禁用 GDScript 模組編譯 Godot 也能使用。

基本使用

要對數學運算式求值,請使用:

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

可以使用以下運算子:

運算子

請注意

其他注意事項

還可以用於連接字串和陣列:- "hello" + " world" = hello world - [1, 2] + [3, 4] = [1, 2, 3, 4]

減法

乘(*

Division (/)

兩個運算元都是整數時執行整數除法。如果至少有一個是浮點數,就會返回浮點值。

求餘(%

返回整數除法的餘數。

運算子周圍的空格是可選的。另外請記住,此處適用一般的`運算次序 <https://zh.wikipedia.org/zh-cn/%E9%81%8B%E7%AE%97%E6%AC%A1%E5%BA%8F>`__。必要時請使用括弧來覆蓋運算子的次序。

Godot 所支援的所有 Variant 型別都可以使用:整數、浮點數、字串、陣列、字典、顏色、向量……

陣列與字典的索引方法與 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

向運算式傳遞變數

你可以將變數傳入運算式。這些變數就會進入這個運算式的“本文”,在運算式中使用就會被替換:

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

變數的名稱和變數的值都**必須**以陣列的形式指定,即便只定義一個變數也是如此。而且,變數名是**大小寫敏感**的。

為運算式設定基礎實例

運算式預設的基礎實例是 null。這意味著該運算式沒有關聯基礎實例。

呼叫 Expression.execute() 時,你可以將參數 base_instance 的值設為 self、另一個腳本實例、單例等特定物件的實例:

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

關聯基礎實例可以實作以下功能:

  • 在運算式中引用實例的常數(const)。

  • 在運算式中引用實例的成員變數(var)。

  • 在運算式中呼叫定義在實例上的方法,並使用其返回值。

警告

將基礎實例設為非 null 值,就可以引用常數、成員變數、呼叫定義在該實例的附加腳本中的方法。允許使用者輸入運算式可能會導致在你的遊戲出現作弊,如果你允許任意客戶的在其他玩家的裝置上運作運算式的話,甚至還可能引入安全隱患。

GDScript 範例

下面的腳本演示的是 Expression 類的功能:

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

腳本的功能

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

內建函式

All methods in the Global Scope are available in the Expression class, even if no base instance is bound to the expression. The same parameters and return types are available.

然而,與 GDScript 不同,參數**始終是必須的**,即使類參考中說明此參數為可選。不過,為運算式綁定了基礎實例時,使用者定義函式的參數沒有此限制。