運算式求值
Godot 提供 Expression 類別,可用來計算運算式。
運算式可以是:
數學運算式,例如
(2 + 4) * 16/4.0。布林運算式,例如
true && false。內建函式呼叫,例如
deg_to_rad(90)。如果於呼叫 Expression.execute() 時將
base_instance設為非null,則可以呼叫用戶自訂腳本的方法,如update_health()。
備註
Expression 類別獨立於 GDScript,即使編譯 Godot 時未啟用 GDScript 模組也可使用。
基本用法
要計算數學運算式,請使用:
var expression = Expression.new()
expression.parse("20 + 10*2 - 5/2.0")
var result = expression.execute()
print(result) # 37.5
可用的運算子如下:
運算子 |
說明 |
|---|---|
加法( |
亦可用於串接字串與陣列:- |
減法( |
|
乘法( |
|
除法( |
若兩個運算元皆為整數則執行整數除法;只要其中一個為浮點數則返回浮點數結果。 |
餘數( |
回傳整數除法的餘數(取模)。結果符號與被除數相同。 |
邏輯 AND( |
回傳布林值 AND 的結果。 |
邏輯 OR( |
回傳布林值 OR 的結果。 |
邏輯 NOT( |
回傳布林值 NOT 的結果。 |
運算子前後空格可加可不加。請注意一般的 運算子優先順序 依然適用。有需要時可用括號改變運算順序。
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 值後,可於運算式中引用其常數、成員變數,並呼叫該實例所附加腳本內定義的所有方法。若允許玩家自行輸入運算式,可能導致遊戲作弊,若允許任意客戶端在其他玩家裝置上執行運算式,更可能產生資安風險。
範例腳本
以下腳本展示 Expression 類別的多種用途:
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
此腳本的輸出為:
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
內建函式
Global Scope 中的所有方法皆可於 Expression 類別中直接使用,即使未綁定基礎實例亦可。方法參數與回傳型別相同。
但與 GDScript 不同,這些函式的所有參數**皆必填**,即使在類別文件中標記為可選也一樣。若有綁定基礎實例,則自訂函式則不受此限制。