Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Godot Android-Plugins

Einführung

Android-Plugins sind leistungsstarke Werkzeuge zur Erweiterung der Fähigkeiten der Godot-Engine, indem sie die von Android-Plattform und -Ökosystem bereitgestellten Funktionen nutzen.

In Godot 4 werden beispielsweise Android-Plugins verwendet, um mehrere Android-basierte XR-Plattformen zu unterstützen, ohne die Kern-Codebasis mit herstellerspezifischem Code oder Binärdateien zu belasten.

Android-Plugins

Version 1 (v1) des Android-Plugin-Systems wurde in Godot 3 eingeführt und ist mit Godot 4.0 und 4.1 kompatibel. Diese Version ermöglichte es Entwicklern, die Godot-Engine mit Java-, Kotlin- und nativen Funktionen zu erweitern.

Ab Godot 4.2 werden Android-Plugins, die auf der v1-Architektur basieren, nicht mehr verwendet. Stattdessen wird mit Godot 4.2 eine neue Version 2 (v2) Architektur für Android-Plugins eingeführt.

v2-Architektur

Bemerkung

Das Godot Android Plugin nutzt das Gradle Build System.

Aufbauend auf der vorherigen v1-Architektur werden Android-Plugins weiterhin von der Android-Archivbibliothek abgeleitet.

Im Kern ist ein Godot Android Plugin v2 eine Android-Bibliothek mit einer Abhängigkeit von der Godot Android-Bibliothek und einem benutzerdefinierten Android-Bibliotheksmanifest.

Diese Architektur ermöglicht es Android-Plugins, die Funktionalität der Engine mit Folgendem zu erweitern:

  • APIs der Android-Plattform

  • Android-Bibliotheken

  • Kotlin- und Java-Bibliotheken

  • Native Bibliotheken (über JNI)

  • GDExtension-Bibliotheken

Jedes Plugin hat eine Init-Klasse, die von der Klasse GodotPlugin abgeleitet ist, die von der Godot Android Bibliothek bereitgestellt wird.

Die Klasse GodotPlugin bietet APIs, um auf die laufende Godot-Instanz zuzugreifen und sich in ihren Lebenszyklus einzuklinken. Sie wird zur Laufzeit von der Godot-Engine geladen.

v2-Packaging-Format

v1 Android-Plugins erforderten eine eigene gdap-Konfigurationsdatei, die vom Godot-Editor verwendet wurde, um die Plugins zu erkennen und zu laden. Dieser Ansatz hatte jedoch mehrere Nachteile, von denen der wichtigste darin bestand, dass es ihm an Flexibilität mangelte und er vom bestehenden Godot-EditorExportPlugin-Format, -Bereitstellungs- und -Installationsfluss abwich.

Dieses Problem wurde für Android-Plugins der Version 2 behoben, indem der Paketierungs- und Konfigurationsmechanismus gdap zugunsten des bestehenden Godot-Paketierungsformats EditorExportPlugin veraltet wurde. Die EditorExportPlugin-API wurde ihrerseits erweitert, um Android-Plugins korrekt zu unterstützen.

Erstellung eines v2-Android-Plugins

Eine Github-Projektvorlage wird unter https://github.com/m4gr3d/Godot-Android-Plugin-Template als Schnellstart für die Erstellung von Godot-Android-Plugins für Godot 4.2+ bereitgestellt. Sie können der Vorlage-README folgen, um Ihr eigenes Godot-Android-Plugin-Projekt einzurichten.

Zum besseren Verständnis werden im Folgenden die Schritte zur Erstellung der Projektvorlage erläutert:

  1. Erstellen Sie ein Android-Bibliotheksmodul mit diesen Anweisungen

  2. Add the Godot Android library as a dependency by updating the module's gradle build file:

    dependencies {
        implementation("org.godotengine:godot:4.2.0.stable")
    }
    

Die Godot-Android-Bibliothek wird auf MavenCentral gehostet und bei jeder Veröffentlichung aktualisiert.

  1. Erstellen Sie GodotAndroidPlugin, eine Init-Klasse für das Plugin, die GodotPlugin erweitert.

    • If the plugin exposes Kotlin or Java methods to be called from GDScript, they must be annotated with @UsedByGodot. The name called from GDScript must match the method name exactly. There is no coercing snake_case to camelCase. For example, from GDScript:

      if Engine.has_singleton("MyPlugin"):
          var singleton = Engine.get_singleton("MyPlugin")
          print(singleton.myPluginFunction("World"))
      
    • Wenn das Plugin Signale verwendet, muss die init-Klasse den Satz der verwendeten Signale durch Überschreiben von GodotPlugin::getPluginSignals() zurückgeben. Um Signale auszusenden, kann das Plugin die Methode GodotPlugin::emitSignal(...) verwenden.

  2. Update the plugin AndroidManifest.xml file with the following meta-data:

    <meta-data
        android:name="org.godotengine.plugin.v2.[PluginName]"
        android:value="[plugin.init.ClassFullName]" />
    

Wobei:

  • PluginName der Name des Plugins ist

  • plugin.init.ClassFullName der vollständige Komponentenname (Paket + Klassenname) der Plugin-Init-Klasse (z.B.: org.godotengine.plugin.android.template.GodotAndroidPlugin) ist.

  1. Erstellen Sie die EditorExportPlugin-Konfiguration, um das Plugin zu verpacken. Die Schritte zum Erstellen der Konfiguration sind im Abschnitt Paketieren eines v2-Android-Plugins zu sehen.

Erstellen eines v2-Android-Plugins mit GDExtension-Funktionen

Ähnlich wie die GDNative-Unterstützung in v1-Android-Plugins, unterstützen v2-Android-Plugins die Fähigkeit, GDExtension-Funktionen zu integrieren.

Eine Github-Projektvorlage wird unter https://github.com/m4gr3d/GDExtension-Android-Plugin-Template als Schnellstart für die Erstellung von GDExtension Android-Plugins für Godot 4.2+ bereitgestellt. Sie können der README der Vorlage folgen, um Ihr eigenes Godot-Android-Plugin-Projekt einzurichten.

Migrieren eines Android-Plugins von v1 nach v2

Führen Sie die folgenden Schritte aus, wenn Sie ein Android-Plugin der Version 1 haben, das Sie auf die Version 2 migrieren möchten:

  1. Aktualisieren Sie die Manifestdatei des Plugins:

    • Ändern Sie das Präfix org.godotengine.plugin.v1 in org.godotengine.plugin.v2

  2. Aktualisieren Sie die Build-Abhängigkeit der Godot Android-Bibliothek:

    • Sie können weiterhin die Binärdatei godot-lib.<Version>.<Status>.aar von Godot's download page verwenden, wenn Sie das bevorzugen. Stellen Sie sicher, dass es auf die neueste stable-Version aktualisiert ist.

    • Or you can switch to the MavenCentral provided dependency:

dependencies {
    implementation("org.godotengine:godot:4.2.0.stable")
}
  1. Nachdem Sie die Godot-Android-Bibliotheksabhängigkeit aktualisiert haben, synchronisieren oder erstellen Sie das Plugin und beheben Sie etwaige Kompilierungsfehler:

    • The Godot instance provided by GodotPlugin::getGodot() no longer has access to an android.content.Context reference. Use GodotPlugin::getActivity() instead.

  2. Löschen Sie die gdap-Konfigurationsdatei(en) und folgen Sie den Anweisungen im Abschnitt Paketierung eines v2-Android-Plugins, um die Plugin-Konfiguration einzurichten.

Paketierung eines v2-Android-Plugins

Wie bereits erwähnt, wird ein v2 Android-Plugin jetzt als EditorExportPlugin-Plugin für den Godot-Editor zur Verfügung gestellt, so dass es viele der gleichen Paketierungsschritte teilt.

  1. Fügen Sie die Plugin-Ausgabe-Binärdateien in das Plugin-Verzeichnis ein (z.B.: in addons/<plugin_name>/)

  2. Fügen Sie das Toolskript für die Exportfunktionalität in das Plugin-Verzeichnis ein (z.B.: in addons/<plugin_name>/)

    • Das erstellte Skript muß ein @tool-Skript sein, sonst funktioniert es nicht richtig

    • The export tool script is used to configure the Android plugin and hook it within the Godot Editor's export process. It should look something like this:

@tool
extends EditorPlugin

# A class member to hold the editor export plugin during its lifecycle.
var export_plugin : AndroidExportPlugin

func _enter_tree():
    # Initialization of the plugin goes here.
    export_plugin = AndroidExportPlugin.new()
    add_export_plugin(export_plugin)


func _exit_tree():
    # Clean-up of the plugin goes here.
    remove_export_plugin(export_plugin)
    export_plugin = null


class AndroidExportPlugin extends EditorExportPlugin:
    # Plugin's name.
    var _plugin_name = "<plugin_name>"

    # Specifies which platform is supported by the plugin.
    func _supports_platform(platform):
        if platform is EditorExportPlatformAndroid:
            return true
        return false

    # Return the paths of the plugin's AAR binaries relative to the 'addons' directory.
    func _get_android_libraries(platform, debug):
        if debug:
            return PackedStringArray(["<paths_to_debug_android_plugin_aar_binaries>"])
        else:
            return PackedStringArray(["<paths_to_release_android_plugin_aar_binaries>"])

    # Return the plugin's name.
    func _get_name():
        return _plugin_name


- Here are the set of `EditorExportPlugin APIs <https://docs.godotengine.org/en/stable/classes/class_editorexportplugin.html>`_ most relevant to use in this tool script:

    - `_supports_platform <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-supports-platform>`_: returns ``true`` if the plugin supports the given platform. For Android plugins, this must return ``true`` when ``platform`` is `EditorExportPlatformAndroid <https://docs.godotengine.org/en/stable/classes/class_editorexportplatformandroid.html>`_
    - `_get_android_libraries <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-libraries>`_: retrieve the local paths of the Android libraries binaries (AAR files) provided by the plugin
    - `_get_android_dependencies <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-dependencies>`_: retrieve the set of Android maven dependencies (e.g: `org.godot.example:my-plugin:0.0.0`) provided by the plugin
    - `_get_android_dependencies_maven_repos <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-dependencies-maven-repos>`_: retrieve the urls of the maven repos for the android dependencies provided by ``_get_android_dependencies``
    - `_get_android_manifest_activity_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-activity-element-contents>`_: update the contents of the `<activity>` element in the generated Android manifest
    - `_get_android_manifest_application_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-application-element-contents>`_: update the contents of the `<application>` element in the generated Android manifest
    - `_get_android_manifest_element_contents <https://docs.godotengine.org/en/latest/classes/class_editorexportplugin.html#class-editorexportplugin-method-get-android-manifest-element-contents>`_: update the contents of the `<manifest>` element in the generated Android manifest

    The ``_get_android_manifest_*`` methods allow the plugin to automatically provide changes
    to the app's manifest which are preserved when the Godot Editor is updated, resolving a long standing issue with v1 Android plugins.
  1. Create a plugin.cfg. This is an INI file with metadata about your plugin:

[plugin]

name="<plugin_name>"
description="<plugin_description>"
author="<plugin_author>"
version="<plugin_version>"
script="<relative_path_to_the_export_tool_script>"

Zur Veranschaulichung sehen Sie hier die Ordnerstruktur für die Godot Android Plugin-Projektvorlage. Zur Build-Zeit wird der Inhalt des Verzeichnisses export_scripts_template sowie die generierten Plugin-Binärdateien in das Verzeichnis addons/<plugin_name> kopiert:

export_scripts_template/
|
+--export_plugin.gd         # export plugin tool script
|
+--plugin.cfg               # plugin INI file

Paketierung eines v2 Android-Plugins mit GDExtension-Funktionen

For GDExtension, we follow the same steps as for Packaging a v2 Android plugin and add the GDExtension config file in the same location as plugin.cfg.

Als Referenz ist hier die Ordnerstruktur für die GDExtension-Android-Plugin-Projektvorlage. Zur Build-Zeit wird der Inhalt des Verzeichnisses export_scripts_template sowie die generierten Plugin-Binärdateien in das Verzeichnis addons/<plugin_name> kopiert:

export_scripts_template/
|
+--export_plugin.gd         # export plugin tool script
|
+--plugin.cfg               # plugin INI file
|
+--plugin.gdextension       # GDExtension config file

Here is what the plugin.gdextension config file should look like:

[configuration]

entry_symbol = "plugin_library_init"
compatibility_minimum = "4.2"
android_aar_plugin = true

[libraries]

android.debug.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/debug/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
android.release.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/release/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
...

Erwähnenswert ist das Feld android_aar_plugin, das angibt, dass dieses GDExtension-Modul als Teil eines v2 Android-Plugins bereitgestellt wird. Während des Exportvorgangs wird dies dem Godot-Editor an, dass die nativen Shared-Libraries der GDExtension-Bibliotheken von den AAR-Binärdateien des Android-Plugins exportiert werden.

Für GDExtension-Android-Plugins muss die Plugin-Init-Klasse GodotPlugin::getPluginGDExtensionLibrariesPaths() überschreiben und die Pfade zu den gebündelten GDExtension-Bibliotheks-Konfigurationsdateien (*.gdextension) zurückgeben.

Die Pfade müssen relativ zum Verzeichnis assets der Android-Bibliothek sein. Zur Laufzeit wird das Plugin diese Pfade der Godot-Engine zur Verfügung stellen, die sie zum Laden und Initialisieren der gebündelten GDExtension-Bibliotheken verwenden wird.

Verwenden eines v2 Android-Plugins

Bemerkung

  • Godot 4.2 oder höher ist erforderlich

  • v2-Android-Plugin erfordert die Verwendung des Gradle-Build-Prozesses.

  • Die mitgelieferten Github-Projektvorlagen enthalten Demo-Godot-Projekte für schnelle Tests.

  1. Kopieren Sie das Ausgabeverzeichnis des Plugins (addons/<plugin_name>) in das Verzeichnis des Ziel-Godot-Projekts

  2. Öffnen Sie das Projekt im Godot-Editor; der Editor sollte das Plugin erkennen

  3. Navigieren Sie zu Projekt -> Projekteinstellungen -> Plugins, und stellen Sie sicher, dass das Plugin aktiviert ist

  4. Installieren Sie die Godot-Android-Build-Vorlage, indem Sie auf Projekt -> Android Build Template installieren... klicken

  5. Navigieren Sie zu Projekt -> Exportieren...

  6. Erstellen Sie im Fenster Export eine Android Exportvorgabe

  7. In der Vorgabe Android-Export scrollen Sie zu Gradle-Build und setzen Gradle-Build verwenden auf true

  8. Update the project's scripts as needed to access the plugin's functionality. For example:

if Engine.has_singleton("MyPlugin"):
        var singleton = Engine.get_singleton("MyPlugin")
        print(singleton.myPluginFunction("World"))
  1. Schließen Sie ein Android-Gerät an Ihren Rechner an und führen Sie das Projekt darauf aus

Verwendung eines v2-Android-Plugins als Android-Bibliothek

Da sie auch Android-Bibliotheken sind, können Godot v2-Android-Plugins aus ihrer EditorExportPlugin-Paketierung herausgenommen und als rohe AAR-Binärdateien zur Verwendung als Bibliotheken neben der Godot Android-Bibliothek durch Android-Anwendungen bereitgestellt werden.

Wenn Sie für diesen Anwendungsfall entwickeln, stellen Sie sicher, dass Sie zusätzliche Anweisungen einfügen, wie die AAR-Binärdateien eingebunden werden sollen (z.B.: eigene Ergänzungen zum Manifest der Android-App).

Referenzimplementierungen

Tipps und Leitlinien

Vereinfachen Sie den Zugang zu den exponierten Java / Kotlin APIs

Um den Zugriff auf die exponierten Java-/Kotlin-APIs im Godot-Editor zu erleichtern, wird empfohlen, eine (oder mehrere) gdscript-Wrapper-Klasse(n) bereitzustellen, mit der/denen sich die Benutzer Ihres Plugins verbinden können.

Zum Beispiel:

class_name PluginInterface extends Object

## Interface used to access the functionality provided by this plugin.

var _plugin_name = "GDExtensionAndroidPluginTemplate"
var _plugin_singleton

func _init():
    if Engine.has_singleton(_plugin_name):
        _plugin_singleton = Engine.get_singleton(_plugin_name)
    else:
        printerr("Initialization error: unable to access the java logic")

## Print a 'Hello World' message to the logcat.
func helloWorld():
    if _plugin_singleton:
        _plugin_singleton.helloWorld()
    else:
        printerr("Initialization error")

Unterstützung der GDExtension-Funktionalität im Godot-Editor

Wenn Sie die Funktionalität der GDExtension im Godot-Editor verwenden möchten, wird empfohlen, die nativen Binärdateien der GDExtension nicht nur für Android zu kompilieren, sondern auch für das Betriebssystem, auf dem die Entwickler / Benutzer den Godot-Editor ausführen möchten. Andernfalls könnten Entwickler / Benutzer daran gehindert werden, Code zu schreiben, der vom Godot-Editor aus auf das Plugin zugreift.

Dies kann das Erstellen von Dummy-Plugins für das Host-Betriebssystem beinhalten, nur damit die API im Editor veröffentlicht wird. Sie können die GitHub-Vorlage godot-cpp-template als Referenz verwenden, wie das geht.

Supported data types

All data types are supported. Common types are mapped to their Godot equivalents (for example, String[] is mapped to PackedStringArray()), but for other types, you can use JavaClassWrapper to access it.

Godot stürzt beim Laden ab

Check adb logcat for possible problems.