【Godot】文字列で変数や関数にアクセスする方法

この記事では、文字列指定で変数や関数にアクセスする方法について書きます。

get() / set() で変数を操作する

GDScriptでは、get() / set() を使うことで文字列で変数にアクセスできます。

extends Node2D

var hp = 1

func _ready():
    print("hp: %d"%hp)

    # 文字列で "hp" から値を取得する
    print("hp: %d"%get("hp"))

    # 文字列で "hp" に値を設定する
    set("hp", 100)
    print("hp: %d"%hp)

実行結果は以下のとおりです。

実行結果
hp: 1
hp: 1
hp: 100

call() で関数を呼び出す

call() を使用すると関数を名前で呼び出すことができます。

extends Node2D

func hoge():
    print("hoge")

func piyo(v):
    print("piyo", v)

func _ready():
    # 関数 "hoge" を名前で呼び出し
    call("hoge")

    # 関数 "piyo" に引数 "123" を指定して呼び出し
    call("piyo", 123)

実行結果は以下のとおりです。

実行結果
hoge
piyo123

名前で呼び出すと何が便利なのかというと、例えばIDに対応する関数呼び出しを簡素な記述にできることです。

extends Node2D

func ai_1():
    print("AI処理1を実行")

func ai_2():
    print("AI処理2を実行")

func ai_3():
    print("AI処理3を実行")

func exec_ai(id):
    # idに対応する処理を呼び出す
    match id:
        1:
            ai_1()
        2:
            ai_2()
        3:
            ai_3()
        _:
            ai_1()

func _ready():
    # 各AI処理を実行
    exec_ai(1)
    exec_ai(2)
    exec_ai(3)  

AI処理1〜3がある場合に、exec_ai() で match を使ってIDに対応する呼び出しを記述しています。ただこの書き方だと、AI処理を追加するたびに match文で IDに対応する処理を書かなければいけません。

そこで call() を使うと以下のように簡素化できます。

func exec_ai(id):
    # idに対応する処理を呼び出す
    var func_name = "ai_%d"%id
    if has_method(func_name):
        # 対象の関数名が存在していたら実行
        call(func_name)
    else:
        # 存在しない場合はひとまず1番を実行
        ai_1()

の書き方をすることで、AI処理が増えても呼び出し部分を修正する必要がなくなります。
注意点として、has_method() で対象の関数が存在するかどうかをチェックして、適切なエラー処理を行います。

参考