从此
📄文章 #️⃣专题 🌐酷站 👨‍💻技术 📺 📱

游戏编程开发 手机版(Android、iOS)

综合

主流游戏手机系统为 Android、iOS;端游系统主要是Windows。

Godot 游戏运行时,若不支持 Vulkan 则会自动降级至 OpenGL,但可以不允许并同时弹框:rendering/rendering_device/fallback_to_opengl3
  GD.Print("显卡:" + RenderingServer.GetVideoAdapterName());
  //GD.Print("runtime rendering-driver - " + RenderingServer.GetCurrentRenderingDriverName() + " | 1/3 - " + RenderingServer.GetCurrentRenderingMethod()); // Godot v4.4+

Godot v4.4+ 访问 Android Java 类:似乎还未支持Get("字段名")!?
  var cls = JavaClassWrapper.Wrap("java.lang.String"); // or com/godot/game/GodotApp
  if (cls != null) { // 构造函数方法名即类名"String",但也可用"<init>"。
    cls.GetJavaMethodList().Cast().ToList().ForEach(x => GD.Print(x));
    OS.Alert(cls.GetJavaClassName()); GD.Print(cls.Call("<init>").As<JavaObject>());
  }
Godot v4.4+ Android模板启用了可自定义的常量类:buildFeatures { buildConfig = true }

权限申请用 OS.request_permission("android.permission.POST_NOTIFICATIONS")



Godot 手机游戏导出

  反直觉:语言标识zh有效,而zh_CN和cmn_CN则不识别 - config/name_localized={"zh": "游戏名","zh_CN": "换用zh"}

  密钥:
    由于 .godot\export_credentials.cfg 保存了 android 密钥信息,可能被清除,故使用环境变量设置:

    Android环境变量 GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD 高于 keystore/release_password="" 取值;若存在第二个证书,就手动填入一下。

    [Environment]::SetEnvironmentVariable("GODOT_ANDROID_KEYSTORE_RELEASE_PATH", "D:\main\docs\app\android-2022-p12.keystore", 'User')
    [Environment]::SetEnvironmentVariable("GODOT_ANDROID_KEYSTORE_RELEASE_USER", "v2android", 'User')
    [Environment]::SetEnvironmentVariable("GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD", "[证书密码]", 'User')

  Godot Android非自定义构建方式:
    【仅用到】部署用 Android SDK Platform-Tools的platform-tools\adb 和编译用 Android SDK Build-Tools的build-tools\34.0.0\apksigner

  Godot Android模板
    Godot 4.3+写死了JDK17版本 - https://github.com/godotengine/godot/issues/88116
      java_sdk_path 虽然可以被 JAVA_HOME 指定,但会破环开发环境 JAVA 版本,故写死压缩包释放的JDK。

      必须在【编辑器设置→导出→Android】中指定java_sdk_path(必须Java17版本 E:/java/jdk-17_windows-x64_bin/jdk-17.0.12 );而android_sdk_path则可选,若IDE导出时未定义ANDROID_HOME环境变量,则会回落至 %LOCALAPPDATA%/Android/Sdk 。
      [环境变量ANDROID_HOME值]:[Environment]::SetEnvironmentVariable("ANDROID_HOME", "C:\Users\person\AppData\Local\Android\Sdk", 'User')
      指定java_sdk_path后会自动触发调试证书的生成(export/android/debug_keystore) C:/Users/person/AppData/Roaming/Godot/keystores/debug.keystore
      

    [可选/定制自己的JDK和Gradle版本]: 
     androidGradlePlugin版本当前保持在7.x,gradle v7.6.3最高支持JDK19;Godot v4.2暂不支持AGP8.x,因AndroidManifest.xml大改了package位置。
     修改 config.gradle
      androidGradlePlugin: '7.4.2',
     修改 gradle.properties - 等同 编辑器设置 中的 java_sdk_path
      org.gradle.java.home=C:\\Program Files\\Java\\jdk-19
     修改 gradle\wrapper\gradle-wrapper.properties
      distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip

  TouchScreenButton - 专用于触摸屏设备支持多点触摸的Button按钮控件。

Godot Android

Godot导出Android:
  导出用调试Key文件debug.keystore密钥 - 
Debug Keystore User(不区分大小写):AndroidDebugKey
Debug Keystore Pass:android 官网导出教程 - https://docs.godotengine.org/zh_CN/stable/tutorials/export/exporting_for_android.html#setting-it-up-in-godot 导出文件大小 - “使用gradle构建”+ C#脚本 打包的apk为103MiB;“使用gradle构建”打包的apk为73MiB;纯GDScript以压缩方式打包的apk则为23MiB。 亲测发现问题 - 勾选“使用gradle构建”打包后大小竟然100MB左右,不勾则50MB左右,手动解压发现实际文件大小一样的,再压缩的话,100MB的也能压缩回50MB了!压缩率?

Godot iOS/XCode 导出

说明:
  因MoltenVK库锁死了版本,故兼容的iOS版本最低13.x起,更低版本则可改用兼容模式+指定vulkan_sdk_path版本? - https://github.com/godotengine/godot/issues/98791#issuecomment-2453549812
  iPhone不支持Vulkan,但可通过MoltenVK库转译至Metal;Metal is only supported on iOS 14.0+。
  vmware的macOS版Godot只能通过--rendering-driver opengl3启动,且默认白屏,需点击最大化再还原,窗口才能正常显示。

iOS导出: https://www.youtube.com/watch?v=x_ZFAV2id3I
  说明 - 最低iOS版本首选支持Metal的14.0,模拟器用不带Pro的iPhone15;
    亲测Godot v4.3和4.4dev5编辑器,设最低iOS版本为14.0、12.4,用兼容模式(即[rendering]配置项renderer/rendering_method.mobile="gl_compatibility" / Mobile和Forward Plus均闪退),Debug模式导出,成功跑在iPhone15模拟器中。

  iOS导出时必须提供Apple团队ID(10个字符/Xcode中登录Apple账号方能看到):application/app_store_team_id="NJLZXFDD46" 和AppID值 application/bundle_identifier="v43.ios.demo"

  在开发者账户的顶部导航栏中,点按“会员资格详细信息”以查看团队 ID。
  团队ID若未付费则可填入免费TeamID,但要设置为Development:application/export_method_release=1
  获取免费、短期的真机TeamID
  可选 - GODOT_IOS_PROFILE_SPECIFIER_DEBUG环境变量及参数可指定Provisioning Profile Name而非Profile UUID,以避免自动管理描述文件了。 

  安装.NET: 下载x64安装器 dotnet-sdk-9.0.100-osx-x64.pkg,点开Next到底,装完测试 dotnet --info
  鼠标双击 Godot_v4.3-stable_mono_macos.universal.zip 会自动解压至 Godot_mono.app
  导出命令行:Godot_mono.app --export-release "iOS" x.dmg

  注意 - unzip命令可解压*.tpz文件。

  解决“项目列表”窗口提示显卡不支持问题,无法解决主窗口白屏问题,但菜单点开的窗口(“管理到处模板”“导出”等)则正常。
    cd /Users/imacos.top/Desktop/v43-ios-demo/
    /Users/imacos.top/Desktop/Godot_mono.app/Contents/MacOS/Godot --rendering-driver opengl3
    /Users/imacos.top/Desktop/Godot_mono.app/Contents/MacOS/Godot --rendering-driver opengl3 -e
  导出 - 必须“修复导入”ETC2/ASTC报错(勾上“rendering/textures/vram_compression/import_etc2_astc”);亲测Debug模式导出是成功的,Release模式则报错!
    mkdir godot-xcode/
    /Users/imacos.top/Desktop/Godot_mono.app/Contents/MacOS/Godot --path /Users/imacos.top/Desktop/v43-ios-demo/ --headless --export-release "iOS" ../godot-xcode/x.ipa --quit -v
    导出的目录有 x.ipa、x.codeproj 等文件。
  安装ipa:
    iTunes、分发描述文件? 或 Xcode -> Window -> Devices and Simulators -> 推拽 *.ipa 至 Installed Apps


  个人开发者Apple ID(不缴费获取团队id) :
    https://medium.com/@phillipdev/exporting-to-ios-using-godot-4-1-for-free-ed99b8f594b7
  官方便捷调试教程
    https://docs.godotengine.org/zh-cn/4.x/tutorials/export/exporting_for_ios.html

Godot 手机编程

Android模板目录自定义 -  4.3起 gradle_build_directory 可设置 "res://android/build" 中的 "res://android/"部分。
Gradle自定义构建时,APK不会包含下划线开头的目录,比如“_example/”。
屏幕方向 - 
  整个游戏程序只存在一个 com.godot.game.GodotApp 的 Activity 窗口,其他窗口则为 Fragment。
  默认横屏android:screenOrientation="landscape",ScreenOrientation枚举还不支持"unspecified"项;
  landscape不会感应设备方向切换,只能代码设置整个游戏程序的方向,返回窗口也要重新还原方向:
    DisplayServer.ScreenSetOrientation(DisplayServer.ScreenOrientation.Portrait);
    注意 - 支持 Landscape(锁死横屏) 或 SensorLandscape(传感器横屏时总朝上,无视竖屏) 或 Sensor(完全根据传感器切换)

Android上下文单例:
	// 4.4+ 起 Android 环境才会存在 AndroidRuntime 单例,只需判 null 而无需检测平台 HasFeature。
	var ar = Engine.HasSingleton("AndroidRuntime") ? Engine.GetSingleton("AndroidRuntime") : null;
	if (ar != null) { Engine.GetSingleton("AndroidRuntime").Call("getActivity"); }

其他