mcpField
M
mobile-development

mobile-development

github.com/jame581開発930173 回インストール2 週間前に更新
リポジトリ

mobile-development について

Godot 4.x のゲームを Android と iOS に公開する開発者向けのモバイル開発スキルです。署名、ライフサイクル、権限、デバイス API、性能設定など、各プラットフォーム固有の事項を扱います。

主な機能

  1. 01Android と iOS のエクスポートと署名
  2. 02アプリの一時停止・再開処理
  3. 03権限の宣言と実行時リクエスト
  4. 04Java API とデバイス機能の利用
  5. 05セーフエリアと画面向きへの対応
  6. 06モバイル向けレンダラーと性能設定

活用シーン

  1. 01Android のリリース署名と AAB 出力の設定
  2. 02アプリ一時停止時のゲーム状態保存
  3. 03ノッチや画面回転に合わせたレイアウト調整
  4. 04モバイル向けレンダラーとテクスチャ圧縮の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jame581/godotprompter --skill mobile-development

インストール後、Claude Code で/mobile-developmentを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
crash-debugging.md
iap-and-ads.md
plugins.md

詳細

モバイル開発

Godot 4.x のゲームを Android と iOS にリリースします。一般的なエクスポートに加えて、署名、ライフサイクル、権限、プラグイン、IAP、デバイス機能、モバイルレンダラーとパフォーマンス予算に関するプラットフォーム固有の差分を扱います。

関連スキル: 一般的なエクスポートの流れと CI/CD については export-pipeline、セーフエリアのレイアウトについては responsive-ui、タッチ入力については input-handling、モバイルのパフォーマンスについては godot-optimization、C# におけるモバイル固有の注意点については csharp-godot を参照してください。


1. エクスポートと署名

Android: OpenJDK 17 と Android SDK を用意し、Editor Settings で Java SDK Path と Android SDK Path を設定します(ユーザーごとの設定であり、プロジェクトごとではありません)。リリース用キーストアを生成します:

keytool -v -genkey -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000

プリセットの項目:Release / Release User / Release Password(現在、キーストアのパスワードとキーのパスワードは一致している必要があります)。Export With Debug のチェックを外してください。新規の Play へのアップロードには AAB が必須です。 CI の環境変数による上書き:GODOT_ANDROID_KEYSTORE_RELEASE_{PATH,USER,PASSWORD}。

iOS: macOS と Xcode が必要です。エクスポートには App Store Team ID と、逆引き DNS 形式のバンドル Identifier が必要です。Godot は .xcodeproj を生成し、Xcode からビルドします。iOS の シミュレーターでは Compatibility レンダラーを使ってテストしてください。Forward+ と Mobile のサポートは、シミュレーターの Metal に依存します。

カスタム Gradle ビルド(Project → Install the Gradle Build template)は、v2 プラグインと IAP に必須です(Godot 4.2 以降)。Godot 4.7 以降、Use Gradle Build エクスポートオプションは実験的機能の表示がなくなりました(GH-119172)。プラグインまたは IAP が必要な場合は、標準の方法として扱ってください。

⚠️ Godot 4.7 で変更: 非推奨だった Google Play の OBB 拡張ファイルのサポート(apk_expansion/* エクスポートオプション)は、Android エクスポートから削除されました。引き続き APK 拡張ファイルに依存するプロジェクトは、Android App Bundles と Play Asset Delivery に移行するか、以前のロジックを引き継ぐ独立した Godot OBB plugin をインストールしてください。GH-118283 を参照してください。


2. アプリのライフサイクル

実際の Node 通知定数:NOTIFICATION_APPLICATION_PAUSED(2015)、NOTIFICATION_APPLICATION_RESUMED(2014)、NOTIFICATION_APPLICATION_FOCUS_IN/_OUT(2016/2017)、NOTIFICATION_WM_GO_BACK_REQUEST(1007、Android の戻る操作)。モバイルに WM_CLOSE_REQUEST はありません。 PAUSED 時に自動保存してください。iOS では一時停止後、アプリが終了されるまでに処理を完了する猶予は約 5 秒です。

GDScript
func _notification(what: int) -> void:
    match what:
        NOTIFICATION_APPLICATION_PAUSED:
            SaveManager.save_game() # App backgrounded — persist now.
        NOTIFICATION_WM_GO_BACK_REQUEST:
            _confirm_quit()         # Android Back button.
C# の場合

ドキュメントに記載されているのは NotificationWMCloseRequest のみです。以下の PascalCase 名は、同じ命名規則に従っています。

public override void _Notification(int what)
{
    switch ((long)what)
    {
        case NotificationApplicationPaused:
            SaveManager.SaveGame(); // App backgrounded — persist now.
            break;
        case NotificationWMGoBackRequest:
            ConfirmQuit();          // Android Back button.
            break;
    }
}
ピクチャー・イン・ピクチャー(Android、Godot 4.7 以降)

DisplayServer.pip_mode_enter(window_id = 0) はピクチャー・イン・ピクチャーモードに切り替えます。is_in_pip_mode(window_id = 0) は現在の状態を返します。pip_mode_set_aspect_ratio(numerator, denominator, window_id = 0) は PiP ウィンドウのアスペクト比を設定します。pip_mode_set_auto_enter_on_background(auto_enter_on_background, window_id = 0) は、アプリがバックグラウンドに移行したときに PiP に自動で切り替えます。状態遷移は Node 通知として届きます:NOTIFICATION_APPLICATION_PIP_MODE_ENTERED(2019)/NOTIFICATION_APPLICATION_PIP_MODE_EXITED(2020)。いずれも Android 専用です。

func _ready() -> void:
    DisplayServer.pip_mode_set_aspect_ratio(16, 9)
    DisplayServer.pip_mode_set_auto_enter_on_background(true)

func _notification(what: int) -> void:
    match what:
        NOTIFICATION_APPLICATION_PIP_MODE_ENTERED:
            _set_minimal_hud(true)  # PiP window is tiny — hide non-essential UI.
        NOTIFICATION_APPLICATION_PIP_MODE_EXITED:
            _set_minimal_hud(false)
public override void _Ready()
{
    DisplayServer.PipModeSetAspectRatio(16, 9);
    DisplayServer.PipModeSetAutoEnterOnBackground(true);
}

public override void _Notification(int what)
{
    switch ((long)what)
    {
        case NotificationApplicationPipModeEntered:
            SetMinimalHud(true);  // PiP window is tiny — hide non-essential UI.
            break;
        case NotificationApplicationPipModeExited:
            SetMinimalHud(false);
            break;
    }
}

3. 権限

エクスポートプリセットで各権限を permissions/<name> として宣言し、実行時に OS.request_permission(name) で要求します。結果は MainLoop の on_request_permissions_result(permission, granted) を通じて届きます。権限は要求するだけでなく、プリセットでも有効にする必要があります。

GDScript
func _ready():
    if "android.permission.POST_NOTIFICATIONS" not in OS.get_granted_permissions():
        OS.request_permission("android.permission.POST_NOTIFICATIONS")
    get_tree().on_request_permissions_result.connect(_on_perm_result)

func _on_perm_result(permission: String, granted: bool):
    print("%s granted: %s" % [permission, granted])
C# の場合
// Contains() on string[] needs: using System.Linq;
public override void _Ready()
{
    if (!OS.GetGrantedPermissions().Contains("android.permission.POST_NOTIFICATIONS"))
        OS.RequestPermission("android.permission.POST_NOTIFICATIONS");
    GetTree().OnRequestPermissionsResult += OnPermResult;
}

private void OnPermResult(string permission, bool granted)
    => GD.Print($"{permission} granted: {granted}");

4. Android API の呼び出し(JavaClassWrapper)— Godot 4.4+

Godot 4.4 以降。 JavaClassWrapper.wrap("<java.class>")(それ以前から存在しますが、実用的に使えるのは 4.4 以降です)を使うと、プラグインなしで Java/Kotlin クラスを呼び出せます。4.4 で追加された AndroidRuntime シングルトン(Engine.get_singleton("AndroidRuntime"))では、getActivity()、getApplicationContext()、createRunnableFromGodotCallable(callable) を利用できます。

よりシンプルなクロスプラットフォームの方法として、4.4 を必要としない Input.vibrate_handheld(duration_ms, amplitude) があります(VIBRATE 権限が必要です。iOS では iOS 13 以降が必要です)。JavaClassWrapper/AndroidRuntime の全 API、Toast/Intent のレシピ、内部クラスの構文については、Plugins を参照してください。

GDScript
# Godot 4.4+ — requires the VIBRATE permission in the export preset.
func vibrate_ms(duration_ms: int) -> void:
    if Engine.has_singleton("AndroidRuntime"):
        var runtime := Engine.get_singleton("AndroidRuntime")
        var context := runtime.getApplicationContext()
        var vibrator := context.getSystemService("vibrator")
        if vibrator.hasVibrator():
            var Effect = JavaClassWrapper.wrap("android.os.VibrationEffect")
            var effect = Effect.createOneShot(duration_ms, Effect.DEFAULT_AMPLITUDE)
            vibrator.vibrate(effect)
C# 相当のコード

ここでのドキュメントは GDScript のみです。正確な C# の Variant マーシャリング処理(Java の各戻り値に対する .AsGodotObject())は実機でテストされていないため、実際の 4.4 以降の Android ビルドで確認してください。

// Godot 4.4+ — requires the VIBRATE permission in the export preset.
public void VibrateMs(int durationMs)
{
    if (!Engine.HasSingleton("AndroidRuntime")) return;
    var runtime = Engine.GetSingleton("AndroidRuntime");
    var context = runtime.Call("getApplicationContext").AsGodotObject();
    var vibrator = context.Call("getSystemService", "vibrator").AsGodotObject();
    if (vibrator.Call("hasVibrator").AsBool())
    {
        var effect = JavaClassWrapper.Wrap("android.os.VibrationEffect");
        var oneShot = effect.Call("createOneShot", durationMs, effect.Get("DEFAULT_AMPLITUDE"));
        vibrator.Call("vibrate", oneShot);
    }
}
スクリプトから Java インターフェースを実装する(Godot 4.7+)

JavaClassWrapper.create_proxy(object: Object, interfaces: PackedStringArray) -> JavaObject は Godot オブジェクトを使って、指定された Java インターフェースを実装します。オブジェクトのメソッドシグネチャは Java インターフェースのメソッドシグネチャと一致している必要があり、Java からの呼び出しは一致するメソッドに振り分けられます。create_sam_callback(sam_interface: String, callable: Callable) -> JavaObject は、SAM メソッドのパラメーターと戻り値の型に一致する Callable を使って、単一抽象メソッド(SAM)インターフェースを扱います。どちらも Android 以外のすべてのプラットフォームでは null を返します。

class PrintProxy:
    func println(content: String) -> void:
        print(content)

func _demo() -> void:
    var print_proxy := PrintProxy.new()
    var printer := JavaClassWrapper.create_proxy(print_proxy, ["android.util.Printer"])
    printer.println("Hello Godot World!")

    var cb := func(content: String) -> void: print(content)
    var callback := JavaClassWrapper.create_sam_callback("android.util.Printer", cb)
    callback.println("Hello Godot World!")

ここでのドキュメントは GDScript のみです。CreateProxy は登録名でメソッドを照合するため、C# の実装クラスでは Java インターフェースと完全に一致するメソッド名が必要です。C# では CreateSamCallback を使うことをおすすめします。

var cb = Callable.From((string content) => GD.Print(content));
var callback = JavaClassWrapper.CreateSamCallback("android.util.Printer", cb);
callback.Call("println", "Hello Godot World!");

5. デバイス機能とセーフエリア

DisplayServer.get_display_safe_area() -> Rect2i(Android/iOS)は、ノッチや切り欠きの内側にある使用可能な領域を返します。get_display_cutouts()(Android)は切り欠きの矩形を一覧表示します。モーションセンサーは Input から利用できます(Vector3 を返す get_accelerometer/gravity/gyroscope/magnetometer。Android/iOS のみ)。

GDScript
func _ready():
    var safe := DisplayServer.get_display_safe_area() # Rect2i
    $UI.position = safe.position
    $UI.size = safe.size
C# 相当のコード
public override void _Ready()
{
    Rect2I safe = DisplayServer.GetDisplaySafeArea();
    var ui = GetNode<Control>("UI");
    ui.Position = safe.Position;
    ui.Size = safe.Size;
}

ネイティブのファイルダイアログ(DisplayServer.file_dialog_show())は Android でサポートされています。Godot 4.7 以降では、すべてのデバイスでネイティブのファイルピッカーが動作します。FEATURE_NATIVE_DIALOG_FILE のサポートを制限していた Android バージョンのチェックは削除されました(GH-115257)。

Godot 4.7 以降: 画面上のタッチジョイスティックには、自作の TouchScreenButton 構成ではなく、組み込みの VirtualJoystick Control ノードを使ってください。全 API については、input-handling(references/touch.md、「VirtualJoystick (Godot 4.7+)」)を参照してください。

デバイスの向き変更シグナル(Godot 4.7+)

DisplayServer.orientation_changed(orientation: int)(Android/iOS)は、デバイスの向きが変わると発火します。1 は縦向き、2 は横向き、0 は未定義です。

func _ready() -> void:
    DisplayServer.orientation_changed.connect(_on_orientation_changed)

func _on_orientation_changed(orientation: int) -> void:
    _relayout_hud(orientation == 2)  # 1 portrait, 2 landscape, 0 undefined.
public override void _Ready()
{
    DisplayServer.Singleton.Connect(DisplayServer.SignalName.OrientationChanged,
        Callable.From((long orientation) => RelayoutHud(orientation == 2)));
}

6. モバイルのパフォーマンスとレンダラー

Mobile(または Compatibility)レンダラーを使用してください。iOS シミュレーターでは Compatibility をおすすめします。Android のテクスチャ圧縮には、rendering/textures/vram_compression/import_etc2_astc = true(ETC2/ASTC)を有効にしてください。単一アーキテクチャの APK は小さく保ち、AAB はデバイスごとに自動で分割されます。描画呼び出しやバッチ処理の詳細な調整は godot-optimization を参照してください。


7. モバイルでの C#

C# の Android/iOS エクスポートは Godot 4.2 以降で実験的に利用できます。Android の C# エクスポートには .NET 9 以降が必要です(Godot 4.5 の場合)。iOS エクスポートは macOS からのみ実行でき(エクスポート時に arm64 と x86_64 のシミュレーターアセンブリもビルドされます)、C# は Web にエクスポートできません。 C# を使うモバイルプロジェクトで最もリスクが高い部分なので、エクスポートのパイプラインを早い段階でテストしてください。

詳細: Plugins (Android v2 / iOS) · In-app purchases & ads · Crash debugging


実装チェックリスト

  • リリース用キーストア(Android)/プロビジョニング+チーム ID(iOS)を設定済み
  • Play へのアップロードには AAB を使用すること。v2 プラグインまたは IAP を使用する場合は Gradle ビルドをインストール済み
  • NOTIFICATION_APPLICATION_PAUSED に自動保存を接続済み(iOS の約 5 秒の制限を順守)
  • プリセットで必要な権限を有効にし、実行時にもリクエスト済み
  • JavaClassWrapper の使用箇所に Godot 4.4+ が必要である旨を明記。必要に応じて 4.3 用の代替手段を用意
  • UI を get_display_safe_area() 内に配置し、ノッチ/カットアウトに対応
  • モバイル/互換レンダラーと ETC2/ASTC 圧縮を有効化
  • C# プロジェクト:Android 向けのエクスポートに .NET 9+ が必要であることを確認済み
  • Play の OBB/APK 拡張ファイルを Play Asset Delivery を使用する App Bundle に移行するか、Godot OBB プラグインをインストール(組み込みサポートは Godot 4.7 で削除)
  • PiP(Android):アスペクト比と自動開始を設定し、HUD が PIP_MODE 通知に反応するよう設定(Godot 4.7+)

コメント