式の評価

Godotは式の評価に使用できる Expression クラスを提供します。

式は次のとおりです:

  • (2 + 4) * 16/4.0 のような数式。

  • A boolean expression such as true && false.

  • deg_to_rad(90) のような組み込みメソッドの呼び出し。

  • update_health() などのユーザースクリプトに対するメソッド呼び出し ( Expression.execute() を呼び出すときに base_instancenull 以外の値に設定されている場合)。

注釈

ExpressionクラスはGDScriptから独立しています。 GDScriptモジュールを無効にしてGodotをコンパイルした場合でも使用できます。

Basic usage

数式を評価するには、次のコードを使用します:

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]

減算 (-)

乗算 (*)

除算 (/)

両辺が整数の場合は整数の除算を実行します。どちらか1つが浮動小数点数の場合は浮動小数点値を返します。

Remainder (%)

Returns the remainder of an integer division (modulo). The result will always have the sign of the dividend.

Conjunction (&&)

Returns the result of a boolean AND.

Disjunction (||)

Returns the result of a boolean OR.

Negation (!)

Returns the result of a boolean NOT.

演算子の周囲のスペースはオプションです。また通常の 演算子の優先順位 が適用されることに注意してください。必要に応じて括弧を使用して操作の順序を指定します。

Godotでサポートされているすべてのバリアント型 (整数、浮動小数点数、文字列、配列、辞書、色、ベクトルなど) を使用できます…

配列と辞書には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

変数を1つだけ定義する場合でも、変数名と変数値の両方を配列として指定する**必要があります**。また、変数名は**大文字と小文字が区別されます**。

式のベースインスタンスを設定する

デフォルトでは、式のベースインスタンスは 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

ビルトイン関数

グローバルスコープ 内のすべてのメソッドは、ベースインスタンスが式にバインドされていない場合でも、Expressionクラスで使用できます。同じパラメータと戻り値の型が使用できます。

ただしGDScriptとは異なり、クラス参照でオプションとして指定されている場合でも、パラメーターは**常に必須**です。対照的に、ベースインスタンスを式にバインドする場合、引数に関するこの制限はユーザーが作成した関数には適用されません。