创建Android插件¶
介绍¶
在手机游戏货币化出现之前,让视频游戏便携化是一件好事。
这一领域很复杂,通常是一款可以盈利的移动游戏,需要与服务器进行特殊连接,例如:
分析
应用内购买
收据验证
安装跟踪
广告
视频广告
交叉推广
游戏中的软货币和硬货币
促销代码
A/B测试
登录
云保存
排行榜和分数
用户支持和反馈
发布到Facebook、Twitter等。
提醒推送
在iOS上,你可以编写一个C++模块,利用C++与Objc的交互。即使使用gdantive也可以使其成为插件。
在Android上,通过JNI(Java原生接口)与C++接口不是很灵活,因此编写插件是相当多的工作。
也有可能你只想修改Android导出模板,通过使用插件,你的项目可以保持与较新的godot版本兼容(因为Android源模板将在每个版本上更新)。
也许休息一下¶
大多数这些API允许通过REST/JSON API进行通信。如果API相对简单并且不需要复杂的授权,那么这可能比编写特定的Android插件更好。
Godot非常支持HTTP、HTTPS和JSON,因此以这种方式实现的API也可以在每个平台上工作。
当然,在大多数情况下,只写一个Android插件更容易,所以继续阅读。
Android插件¶
编写一个Android插件现在可以开始godot 3.2了。这也很容易!不再需要重新编译引擎。
在进行任何操作之前,请确保您了解如何设置 custom build environment 对于Android。
您的插件需要位于除 "build/" 里面 "res://android" 目录(通过以上链接创建)。任何名称都可以,所以根据要实现的SDK(或者只是插件名称)来命名它。
一旦创建,就有一些规则要遵循,但它们很简单。
Android目录¶
在插件文件夹中,您可以使用标准文件夹,就像它们来自Android Gradle项目一样。例如:
src/ - For Java source code, same as in your Android project
res/ - For resources
aidl/ - For interfaces
assets/ - For assets that will be included as-is on export
libs/debug - For debug JNI libraries
libs/release - For release JNI libraries
Gradle将在构建时自动将它们视为项目的一部分,与默认项目文件相同。
“区块”文件¶
现在可以修改 "AndroidManifest.xml" 和 build.gradle 在里面 "res://android/build" 直接和Godot将保持您的变化时,建设。但问题是,如果更新godot,还需要更新 build/ 文件夹和更改将丢失。
为了克服这个问题,godot android插件系统允许您创建 块 文件,您可以在其中指定可以同时插入 "AndroidManifest.xml" 和 build.gradle . 每次Godot构建用于导出或部署的项目时都会插入它们。
AndroidManifest.conf¶
此文件允许将块的位插入 AndroidManifest.xml ,以下是支持的标记,完全可选:
[user_permissions]
此标记下面的任何文本位都插入到文件的<manifest>标记中。这通常用于权限标记。
[application]
文件的<application>标记内此标记下面的任何文本位。许多SDK都需要这样做。
[application_attribs]
这些是可以添加到<application>标记末尾的属性。有些SDK需要这样做。
gradle.conf¶
此文件允许将块的位插入 build.gradle ,以下是支持的,完全是可选的:
[buildscript_repositories]
此标记下面的任何文本位都插入到生成文件的buildscript.repositories部分中。
[buildscript_dependencies]
此标记下面的任何文本位都插入到生成文件的buildscript.dependencies部分中。
[allprojects_repositories]
此标记下面的任何文本位都插入到构建文件的allprojects.repositories部分中。
[dependencies]
此标记下面的任何文本位都插入到生成文件的依赖项部分中。
[android_defaultconfig]
此标记下面的任何文本位都插入构建文件的android.defaultconfig部分。
[global]
此标记下面的任何文本位都插入到生成文件的全局范围内。
爪哇独生子女¶
Android插件通常会有一个单独的类来加载它,这个类继承自 Godot.SingletonBase
. 为模块提供的任何其他资源的资源标识符将位于 com.godot.game.R
类,因此您可能希望导入它。
单个对象模板如下:
package org.godotengine.godot;
import android.app.Activity;
import android.content.Intent;
import com.godot.game.R;
import javax.microedition.khronos.opengles.GL10;
public class MySingleton extends Godot.SingletonBase {
protected Activity appActivity;
protected Context appContext;
private int instanceId = 0;
public int myFunction(String p_str) {
// A function to bind.
return 1;
}
public void getInstanceId(int pInstanceId) {
// You will need to call this method from Godot and pass in the get_instance_id().
instanceId = pInstanceId;
}
static public Godot.SingletonBase initialize(Activity p_activity) {
return new MySingleton(p_activity);
}
public MySingleton(Activity p_activity) {
// Register class name and functions to bind.
registerClass("MySingleton", new String[]
{
"myFunction",
"getInstanceId"
});
this.appActivity = p_activity;
this.appContext = appActivity.getApplicationContext();
// You might want to try initializing your singleton here, but android
// threads are weird and this runs in another thread, so to interact with Godot you usually have to do.
activity.runOnUiThread(new Runnable() {
public void run() {
// Useful way to get config info from "project.godot".
String key = GodotLib.getGlobal("plugin/api_key");
// SDK.initializeHere();
}
});
}
// Forwarded callbacks you can reimplement, as SDKs often need them.
protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {}
protected void onMainRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {}
protected void onMainPause() {}
protected void onMainResume() {}
protected void onMainDestroy() {}
protected void onGLDrawFrame(GL10 gl) {}
protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // Singletons will always miss first 'onGLSurfaceChanged' call.
}
回电Godot¶
从Java调用Godot更困难一些。必须首先知道脚本的实例ID,这是通过调用 get_instance_ID()
在剧本上。这返回一个可以传递给Java的整数。
从Java中使用 calldeferred
与Godot通信的功能。Java最有可能在一个单独的线程中运行,因此调用被延迟:
GodotLib.calldeferred(<instanceid>, "<function>", new Object[]{param1, param2, etc});
Godot将检测到这个单例并在适当的时候初始化它。
故障排除¶
装载时Godot坠毁¶
检查 adb logcat
对于可能出现的问题,则:
确保libgodot的android.so在
libs/armeabi
文件夹检查Java单子中使用的方法只使用简单的Java数据类型,不支持更复杂的数据类型。
未来¶
Godot有一个实验Java API包装器,它允许使用来自GDScript的整个Java API。
它使用简单,使用方法如下:
class = JavaClassWrapper.wrap(<javaclass as text>)
这很可能还不起作用,如果您想测试它并帮助我们使其正常工作,请在irc.freenode.org上联系我们:godotenengine devel。