【Godot】Steam経由でインストールしたGodot EngineをmacOS環境でコマンドライン起動する方法

Godotでネットワークの実験をしようとしたところ、インスタンスの多重起動で苦戦したのでそのメモとなります。

Godotでネットワークを始めようとした場合には、こちらのページが参考になります。

基本的にこちらのコードをそのままで通信処理が実装できるのですが、通信は「サーバー」と「クライアント」の2つのインスタンスを同時に実行する必要があります。

In Godot 4.0, it will be possible to run multiple project instances directly from the editor thanks to the EditorDebugger refactor. This refactor can't be backported to 3.2.x, though.

Godot 4.0では、EditorDebuggerリファクタリングのおかげで、エディターから直接複数のプロジェクトインスタンスを実行できるようになります。ただし、このリファクタリングを3.2.xにバックポートすることはできません。

In the meantime, start multiple instances from a terminal. See Command line tutorial in the documentation for more information.

それまでの間、ターミナルから複数のインスタンスを起動してください。詳細については、ドキュメントのコマンドラインチュートリアルを参照してください。

how to run more game instance in the editer?

v4.0からエディタから複数起動できるようになりますが、現状(v3.x)ではできないようです。

さらに調べたところ、macOS 環境でGodotをコマンドライン起動する方法がまとめられていたのでこちらを参考にしたところ……

Steam経由でインストールしたのでパスが以下のようになっていた (パスにスペースが含まれている) ため、Aliasの指定がうまく行かず……

/Users/syun77/Library/Application Support/Steam/steamapps/common/Godot Engine/Godot.app/Contents/MacOS/Godot

調べたところ、bashでスペースが含まれている場合は、ダブルクオーテーションをエスケープすることで指定できるとの情報があり以下のように bash_profileに指定……

# Godotのエイリアス
alias godot="\"/Users/syun77/Library/Application Support/Steam/steamapps/common/Godot Engine/Godot.app/Contents/MacOS/Godot\""

これで多重起動して通信ができるようになりました。

ひとまずここまでのコード

通信の実験に使用したコードを残しておきます。元のコードとあまり変更はありませんが……

サーバー側

extends Node2D

var _thread = null
var _socket = null

func _ready():
    # スレッドでサーバーを起動
    _thread = Thread.new()
    _thread.start(self, "_launch")

func _exit_tree() -> void:
    # スレッド終了処理
    _thread.wait_to_finish()

func _launch():
    # サーバーを起動
    var done = false
    
    _socket = PacketPeerUDP.new()
    if(_socket.listen(4242, "127.0.0.1") != OK):
        print("ポート4242に接続エラー")
        done = true
    else:
        print("ローカルホスト ポート4242に接続中...")
    
    while(done != true):
        if(_socket.get_available_packet_count() > 0):
            var data = _socket.get_packet().get_string_from_ascii()
            if(data == "quit"):
                done = true
            else:
                print("データ受信: " + data)
    
    print("サーバー終了")
    _socket.close()

サーバー側はスレッドからの呼び出しに修正しています。

クライアント側

extends Node2D

var _socket = null

func _ready() -> void:
    # ローカルホスト 4242ポートに接続する
    _socket = PacketPeerUDP.new()
    _socket.set_dest_address("127.0.0.1", 4242)

func _on_ButtonHello_pressed() -> void:
    # "Hello" 文字列を送信
    _socket.put_packet("Hello".to_ascii())


func _on_ButtonQuit_pressed() -> void:
    # 終了を送信
    _socket.put_packet("quit".to_ascii())