🚀

【Godot4】exeファイルを実行するランチャーアプリを作った

2024/08/29に公開
1

0. この記事の内容

Godot Engineを用いてexeファイルを登録し、実行するランチャーアプリを作成したので、その紹介と制作時に得た知見などを共有したいと思います。

Gifアニメーション

1. 動機

複数のゲームを展示する機会があり、単に実行ファイルのショートカットを置くだけでは見栄えが悪いため、スクリーンショットや説明文を掲載できるランチャーアプリを作成しました。以前はUnityで開発したランチャーを使用していましたが、古いこともあり使い勝手が悪かったため、最近お気に入りのGodotエンジンを用いて一から作り直すことにしました。

2. 機能

このアプリケーションでは

  • ゲームタイトル
  • ゲーム制作者
  • 説明文
  • ロゴ画像
  • カバー画像
  • スクリーンショット画像
  • 実行ファイルのパス

を登録することができます。登録したゲームはゲームタイトル・ロゴ画像・カバー画像と共に一覧に表示され、クリックすることで制作者と説明文が表示されます。

左下の歯車アイコンからEditableを有効にするとゲームの追加・並べ替え・登録した情報の編集が可能になります。

登録したデータはuser://data.cfgConfigFileを使って保存されています。このアプリの実行ファイルExe Launcher.exeと同じ階層にdata.cfgというファイルがある場合はそちらのデータを優先的に読み込みます。

3. 制作に関して

3.1 設計

シンプルなアプリなので、事前に設計などはしていませんが、

  • イベント駆動
  • 拡張性
  • 再利用性

を意識して作成しました。

クラス図

3.2 ハマったこと

3.2.1 GDScriptからexeファイルを実行する

Godot Docs - OS

OS.execute(path, args)でプロセスを実行できますが、この関数を実行するとメインスレッドがブロックされ、アプリケーションがフリーズしてしまいます。この問題を回避するためには、Threadを用いて別スレッドでプロセスを実行するか、create_process関数を使って独立したプロセスを生成する必要があります。

今回の実装では、プロセス実行中はアプリケーションを操作不能(ただし、フリーズ状態ではない)とし、プロセスが終了した時点で操作を再開できるようにするため、Threadを用いて別スレッドでプロセスを実行し、その終了をawaitで待つように実装しました。

thread = Thread.new()

# 別スレッドでプロセスを実行
thread.start(OS.execute.bind(game_info.exe_file_path, []))

# threadが生存中は待機
while thread.is_alive():
    await get_tree().process_frame

thread.wait_to_finish()

3.2.2 GDScriptから任意のディレクトリをエクスプローラで開く

このアプリでは、データの保存場所を開く機能を実装しました。先述したcreate_processからエクスプローラをコマンドから起動すれば良いのですが、単純にOS.create_process("explorer.exe", [path])としてもパスが正しく認識されず、目的のディレクトリを開くことができませんでした。

様々な試行錯誤の結果、以下のことが判明しました。

最終的に、以下のコードを用いて、任意のディレクトリをエクスプローラで開くことに成功しました。

path = path.replace("/", "\\")
OS.create_process("powershell", ["explorer.exe", path])

4. おわり

Godotは、ゲームエンジンでありながら、Godotエディタ自身がGodotで作られています。そのおかげでUIの関連の機能が豊富で、Unityと比べても使いやすいと感じました。

godot-exe-launcher

プロジェクトファイルはMITライセンスで公開しているので、商用利用も含め、自由に活用できます。自身のプロジェクトに組み込んだり、改造して再配布したりすることも可能です。

Discussion

ominiomini

すげーーーーー!かっちょいいですね!!