多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Godot安卓游戏集成AdMob广告插件:从安装配置到真机调试全攻略

Godot安卓游戏集成AdMob广告插件:从安装配置到真机调试全攻略 1. 项目概述为什么你需要一个靠谱的AdMob插件如果你在用Godot做安卓游戏并且想通过广告变现那你大概率绕不开Google AdMob。但说实话Godot官方并没有内置AdMob支持这意味着你需要自己去找插件、集成SDK、处理一堆平台相关的配置。这个过程对于刚接触移动开发的朋友来说简直就是个“劝退”流程。我见过太多人卡在“插件怎么装”、“广告为什么不显示”、“一导出就崩溃”这些问题上最后不得不放弃。今天要聊的这个Godot Android AdMob 插件就是来填这个坑的。它不是一个新玩意儿而是社区里经过多年迭代、相对成熟的一个解决方案由Poing Studios团队维护。我最近在一个休闲小游戏项目里完整地用了一遍从集成、配置到测试上线踩了不少坑也总结了一套能跑通的流程。这篇文章我就把我亲测有效的安装、配置、使用和调试方法掰开揉碎了讲给你听。目标是让你看完之后能避开我踩过的那些坑顺利地把广告集成到你的Godot安卓游戏里。这个插件的核心价值在于“封装”和“简化”。它把Google Mobile Ads SDK那些复杂的Java/Kotlin接口包装成了Godot引擎里可以直接用GDScript调用的简单节点和函数。你不需要去碰Android Studio工程也不用关心Gradle依赖冲突更不用手动处理那些令人头疼的权限和配置。你只需要关心一件事在游戏的哪个时机调用哪个函数来显示哪种广告。2. 插件生态与版本选择别下错了在动手之前最重要的一步是搞清楚你应该用哪个版本的插件。这一步错了后面所有的努力都可能白费。根据我实测的经验版本混乱是导致集成失败的头号原因。2.1 核心仓库迁移从分散到统一最早这个插件的Android和iOS版本是分开的两个仓库godot-admob-android和godot-admob-ios。但就在不久前维护者宣布将代码迁移到了一个统一的Monorepo单一代码库里即godot-admob-plugin。这意味着你以后找最新的插件、文档和发布版本都应该去这个新的主仓库。注意虽然旧的Android仓库被归档了但里面依然有宝贵的文档和历史版本。对于特定Godot版本比如4.1或更早的用户你可能还是需要去旧仓库找对应的发布包。但如果你是新建项目强烈建议使用Godot 4.2并前往主仓库。2.2 根据你的Godot版本对号入座插件的版本和你的Godot引擎版本是强绑定的。用错了版本轻则功能异常重则项目无法导出。下面这个表格是我根据官方发布信息和实测整理出来的对应关系你可以直接“抄作业”你的Godot版本应使用的插件版本/来源关键说明Godot 4.2 及以上从主仓库godot-admob-plugin下载最新版本。这是当前和未来主要的维护分支功能最全支持Mediation广告聚合。Godot 4.1.x使用旧Android仓库的v3.0.6版本。这是一个稳定版本专门为4.1定制。不要尝试用新版本插件会不兼容。Godot 4.0 或更早使用旧Android仓库的v2.x分支。对于非常老的项目你可能需要回退到这个分支。但强烈建议升级Godot版本。怎么判断自己的Godot版本打开Godot编辑器左上角菜单栏项目 - 项目设置是不对的那里看的是项目格式版本。正确的方法是看编辑器窗口的标题栏或者打开帮助 - 关于窗口。2.3 插件包的结构你下载到的是什么无论从哪个仓库下载你最终得到的都是一个.zip压缩包名字大概长这样poing-godot-admob-android-v4.6.0.zip。解压之后你会看到一个标准的Godot插件目录结构需要被放置在你项目的res://addons/路径下。这里有个关键点这个插件包本身就包含了两个部分编辑器插件用于在Godot编辑器内提供配置界面和下载管理功能可选但推荐。Android导出模板插件这才是真正打包进你APK文件、在手机上运行的核心代码。很多新手会困惑为什么按教程放了文件广告还是不显示往往就是因为只放了其中一部分或者放错了路径。接下来我们就进入具体的安装环节。3. 手把手安装与项目配置安装过程可以分为两大步首先是获取并放置插件文件其次是在Godot项目中进行必要的配置。我会假设你已经在Google AdMob后台创建好了应用和广告单元并获得了App ID和广告单元ID。如果还没有你需要先去做这一步。3.1 步骤一获取与放置插件文件方法A使用编辑器插件自动下载推荐给新手这是最无脑的方法前提是你的Godot版本在4.2以上并且网络环境允许访问GitHub。从主仓库godot-admob-plugin的Release页面下载名为godot-admob-plugin.zip的文件。解压这个zip包将其中的addons/admob文件夹整个复制到你Godot项目的res://addons/目录下。如果addons文件夹不存在就自己创建一个。打开你的Godot项目进入项目 - 项目设置 - 插件。你应该能看到一个名为 “AdMob” 的插件勾选它后面的 “启用” 复选框。启用后Godot编辑器顶部菜单栏会出现一个新的 “工具(Tools)” 菜单里面有一个 “AdMob Download Manager”。点击它选择 “Android - LatestVersion”插件会自动下载并配置好对应你Godot版本的Android插件包。这能最大程度避免版本不匹配的问题。方法B手动下载并放置适合所有版本/网络受限情况根据前面版本选择的表格找到对应的仓库和Release页面。下载对应你Godot版本的.zip文件例如poing-godot-admob-android-v4.6.0.zip。解压这个zip包。注意看里面的结构通常包含一个addons/admob/android/bin目录。在你的Godot项目根目录下创建路径res://addons/admob/android/bin/如果不存在。将解压后bin文件夹里的所有内容通常是.aar和.gdip文件复制到你项目的res://addons/admob/android/bin/目录下。实操心得我强烈推荐方法A。它不仅省去了手动查找版本的麻烦而且这个编辑器插件还提供了其他有用的功能比如快速打开配置脚本。手动方法虽然直接但极易因为下错版本而导致后续步骤全部失败。3.2 步骤二配置Android导出模板与权限插件文件放好后我们需要告诉Godot“在导出安卓版本时请把这个插件一起打包进去。”打开项目 - 项目设置。在左侧列表中找到并展开导出类别点击Android。在右侧的 “Gradle构建” 部分你会看到一个 “使用自定义构建” 的选项。你必须勾选这个选项。这是启用任何Android插件的必要条件因为它会为你的项目生成一个可定制的Android Studio工程框架。点击右上角的 “管理导出预设…”为Android平台创建一个新的导出预设比如叫“Android Release”。在预设的 “权限” 选项卡中确保勾选了以下关键权限INTERNET访问网络广告需要从网络加载。ACCESS_NETWORK_STATE访问网络状态用于判断网络是否可用优化广告请求。可选但推荐com.google.android.gms.permission.AD_ID用于广告标识符在某些地区如欧盟的合规性需要。3.3 步骤三填写你的AdMob App ID这是连接你的游戏和AdMob账户的关键一步。在你的Godot项目文件系统中导航到res://addons/admob/android/目录。找到并打开config.gd这个GDScript文件。这个文件就是插件的核心配置文件。你会看到类似下面的代码extends AdmobConfig class_name AdmobConfigAndroid const APPLICATION_ID ca-app-pub-3940256099942544~3347511713 # 这是Google的测试ID将APPLICATION_ID的值替换成你在AdMob后台为你的安卓应用创建的App ID。注意这不是广告单元IDApp ID的格式类似ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy。重要在开发测试阶段你可以暂时使用Google提供的这个测试ID即上面代码中默认的那个。它只会返回测试广告不会产生收益但可以让你安全地测试广告集成是否正确。在上线前务必替换成你自己的真实App ID。4. 核心功能实现在游戏里显示广告配置搞定后终于可以写代码了。这个插件将广告功能抽象成了几个简单的节点和信号用起来非常直观。4.1 初始化与横幅广告横幅广告是那种固定在屏幕顶部或底部的矩形广告。我们先从它开始因为它最简单。首先你需要在游戏的某个全局脚本比如Autoload的单例或主场景的_ready()函数中初始化广告插件并创建广告实例。extends Node var admob_plugin null var banner_ad null func _ready(): # 1. 获取插件单例 if Engine.has_singleton(AdMob): admob_plugin Engine.get_singleton(AdMob) print(AdMob plugin loaded successfully.) else: print(ERROR: AdMob plugin not found. Check installation.) return # 2. 初始化插件必须先于任何广告操作 # 参数is_for_child_directed_treatment (是否面向儿童), is_personalized (是否个性化广告) admob_plugin.initialize(false, true) # 3. 创建横幅广告实例 # 参数广告单元ID 广告尺寸可选如“BANNER”, “LARGE_BANNER”, “MEDIUM_RECTANGLE” var banner_id ca-app-pub-3940256099942544/6300978111 # 测试横幅ID banner_ad admob_plugin.create_banner(banner_id, admob_plugin.BannerSize.BANNER) # 4. 连接广告事件信号非常重要 banner_ad.connect(banner_loaded, Callable(self, _on_banner_loaded)) banner_ad.connect(banner_failed_to_load, Callable(self, _on_banner_failed_to_load)) banner_ad.connect(banner_clicked, Callable(self, _on_banner_clicked)) # 5. 加载广告 banner_ad.load() func _on_banner_loaded(): print(Banner loaded successfully.) # 广告加载成功后再决定显示它 banner_ad.show() func _on_banner_failed_to_load(error_code): print(Banner failed to load. Error code: , error_code) # 这里可以加入重试逻辑 func _on_banner_clicked(): print(Banner was clicked.)关键点解析Engine.has_singleton(AdMob)这是检查插件是否成功加载的唯一可靠方法。如果返回false说明前面的安装或导出模板配置有误。initialize()必须在创建任何广告之前调用。两个布尔参数关乎法律合规COPPA和GDPR/CCPA你需要根据自己游戏的受众群体谨慎设置。如果不确定可以都设为false非儿童导向、非个性化。create_banner()这只是创建了一个广告对象并没有开始加载。你需要调用load()方法。信号连接这是异步编程的核心。广告的加载、失败、点击都是事件驱动的。你必须连接这些信号到你的处理函数才能知道广告状态并做出响应比如加载成功后再显示。4.2 插页广告与激励视频广告这两种广告都是全屏的但逻辑稍有不同。插页广告Interstitial是强制观看的而激励视频广告Rewarded需要给玩家奖励。插页广告实现var interstitial_ad null func _ready(): # ... 初始化代码同上 ... # 创建插页广告 var interstitial_id ca-app-pub-3940256099942544/1033173712 # 测试插页ID interstitial_ad admob_plugin.create_interstitial(interstitial_id) interstitial_ad.connect(interstitial_loaded, Callable(self, _on_interstitial_loaded)) interstitial_ad.connect(interstitial_failed_to_load, Callable(self, _on_interstitial_failed_to_load)) interstitial_ad.connect(interstitial_closed, Callable(self, _on_interstitial_closed)) interstitial_ad.load() # 预加载一个广告 func show_interstitial(): if interstitial_ad ! null and interstitial_ad.is_loaded(): interstitial_ad.show() else: print(Interstitial not ready yet.) # 可以在这里重新加载 interstitial_ad.load() func _on_interstitial_loaded(): print(Interstitial loaded and ready to show.) func _on_interstitial_closed(): print(Interstitial closed. You can load the next one now.) interstitial_ad.load() # 广告关闭后立即预加载下一个保证下次有广告可看激励视频广告实现 激励视频的关键在于“奖励回调”。玩家必须看完广告或达到可奖励的标准你才能发放奖励。var rewarded_ad null func _ready(): # ... 初始化代码同上 ... # 创建激励视频广告 var rewarded_id ca-app-pub-3940256099942544/5224354917 # 测试激励视频ID rewarded_ad admob_plugin.create_rewarded(rewarded_id) rewarded_ad.connect(rewarded_loaded, Callable(self, _on_rewarded_loaded)) rewarded_ad.connect(rewarded_failed_to_load, Callable(self, _on_rewarded_failed_to_load)) rewarded_ad.connect(rewarded_earned_reward, Callable(self, _on_rewarded_earned_reward)) # 关键信号 rewarded_ad.connect(rewarded_closed, Callable(self, _on_rewarded_closed)) rewarded_ad.load() func show_rewarded_video(): if rewarded_ad ! null and rewarded_ad.is_loaded(): rewarded_ad.show() else: print(Rewarded video not ready.) func _on_rewarded_earned_reward(reward_type, reward_amount): # 这是玩家成功获得奖励的回调 print(Player earned reward: , reward_amount, of , reward_type) # 在这里给你的玩家发放游戏内奖励比如金币、道具、复活机会等。 # 例如GameData.add_coins(reward_amount) # 重要务必在此回调中发放奖励而不是在 _on_rewarded_closed 中因为玩家可能中途关闭广告而没看完。 func _on_rewarded_closed(): print(Rewarded video closed.) rewarded_ad.load() # 关闭后预加载下一个注意事项广告的加载是网络请求需要时间并且可能失败。永远不要假设调用show()的时候广告一定准备好了。一定要用is_loaded()方法检查或者通过监听loaded信号来管理广告状态。良好的做法是在游戏启动或某个场景初始化时预加载广告在需要展示时检查状态展示后立即预加载下一个形成一个流水线。5. 导出、测试与真机调试全流程代码写完了在编辑器里运行是没用的因为广告插件只在导出的Android平台上生效。接下来是打包测试。5.1 导出APK与关键设置打开项目 - 导出。选择你之前配置好的Android导出预设。在 “包” 标签页下仔细填写包名唯一标识格式如com.yourcompany.yourgame。这个必须和你在AdMob后台注册应用时填的包名完全一致版本号/版本名称按需填写。在 “图标” 标签页设置好应用图标。在 “Keystore” 标签页如果你要发布到应用商店需要配置一个发布密钥库。对于调试Godot会自动使用调试密钥你可以先不填。点击 “导出项目”选择一个位置保存你的.apk文件。5.2 使用测试广告单元进行安全测试绝对不要在测试阶段使用真实的广告单元ID这违反了AdMob政策可能导致账号被封禁。务必使用Google提供的测试广告单元ID横幅广告测试IDca-app-pub-3940256099942544/6300978111插页广告测试IDca-app-pub-3940256099942544/1033173712激励视频测试IDca-app-pub-3940256099942544/5224354917这些ID会返回无害的测试广告让你安全地测试布局、点击和关闭等功能。5.3 真机调试与Logcat抓取日志把APK安装到手机后广告没显示先别慌看日志。你需要使用Android Debug Bridge (ADB) 工具。连接手机用USB线连接手机和电脑在手机上开启“开发者选项”和“USB调试”。打开终端/命令提示符使用以下命令过滤查看插件和Godot的日志adb logcat -s poing-godot-admob godot-s表示只显示包含这些标签的日志。poing-godot-admob是插件自身的日志标签。godot是Godot引擎的日志标签。在手机上运行你的游戏并触发广告操作。终端里会滚动输出日志。如何解读常见日志I/poing-godot-admob: Initializing AdMob...插件初始化成功。I/poing-godot-admob: Banner loading with id: ...开始加载横幅广告。I/poing-godot-admob: Banner loaded.广告加载成功。E/poing-godot-admob: Failed to load ad: Error Code 0广告加载失败。错误码0通常表示“内部错误”可能是网络问题、配置错误如App ID不对或AdMob后台设置未完成新创建的广告单元需要几小时才能生效。如果完全看不到poing-godot-admob的日志那说明插件根本没有被加载请回头检查安装和导出模板配置。6. 进阶配置与避坑指南到这里基础功能应该都能跑了。但要想上线一个稳定、合规、收益好的产品还有一些坑要填。6.1 广告位布局与适配横幅广告的位置是可以控制的。在调用banner_ad.show()之前你可以设置它的位置。# 将横幅广告放置在屏幕底部 banner_ad.set_banner_position(admob_plugin.BannerPosition.BOTTOM) # 或者放置在屏幕顶部 # banner_ad.set_banner_position(admob_plugin.BannerPosition.TOP) banner_ad.show()对于全面屏或异形屏手机要确保广告不会和系统的导航栏重叠。通常放在底部是更安全的选择。6.2 GDPR与用户同意对话框UMP如果你的游戏会分发给欧洲经济区EEA的用户法律要求你必须收集用户对个性化广告的同意。这个插件集成了Google的用户消息平台UMP来简化这个流程。你需要先在AdMob后台配置同意书然后在代码中初始化UMP。func _ready(): # 先初始化UMP并请求同意 admob_plugin.request_consent_info_update() # 监听同意状态更新信号 admob_plugin.connect(consent_info_updated, Callable(self, _on_consent_info_updated)) admob_plugin.connect(consent_form_dismissed, Callable(self, _on_consent_form_dismissed)) func _on_consent_info_updated(): var status admob_plugin.get_consent_status() var form_available admob_plugin.is_consent_form_available() if status admob_plugin.ConsentStatus.REQUIRED and form_available: # 需要显示同意表单 admob_plugin.load_consent_form() admob_plugin.show_consent_form() elif status admob_plugin.ConsentStatus.NOT_REQUIRED: # 不需要同意例如用户不在EEA _initialize_ads(false) # 传入是否允许个性化广告 else: # 其他状态如未知按最严格处理默认禁用个性化广告 _initialize_ads(false) func _initialize_ads(is_personalized: bool): # 在这里初始化AdMob使用从UMP获取的个性化设置 admob_plugin.initialize(false, is_personalized) # ... 后续创建广告的代码 ...这个过程稍微复杂但为了合规是必须的。务必仔细阅读插件的UMP相关文档。6.3 广告生命周期管理与内存广告对象是引用计数的如果你在场景切换时创建了新的广告实例记得销毁旧的避免内存泄漏。func _exit_tree(): if banner_ad ! null: banner_ad.destroy() # 销毁广告对象释放资源 banner_ad null特别是在使用插页或激励视频时如果玩家快速连续点击按钮要防止同时创建和展示多个广告实例。6.4 上线前的终极检查清单包名导出APK的包名与AdMob后台注册的包名一字不差。App IDconfig.gd中的APPLICATION_ID已替换为你的真实App ID上线时。广告单元ID代码中的所有测试ID已替换为你在AdMob后台创建的真实广告单元ID。合规性如果面向EEA用户UMP流程已正确集成并测试。权限INTERNET和ACCESS_NETWORK_STATE权限已添加。导出设置“使用自定义构建”已勾选。测试使用测试ID在真机上完整跑通了所有广告流程加载、显示、点击、关闭。错误处理代码中已对广告加载失败等情况做了基本处理如日志记录或重试。7. 常见问题排查实录即使按照教程一步步来你还是可能会遇到问题。下面是我和社区里常见的一些“坑”及其解决方案。问题1导出APK时失败报错“Gradle build failed”。可能原因Android SDK版本不兼容或路径错误。排查打开项目 - 导出 - Android检查 “Gradle构建” 下的SDK路径是否正确指向了你的Android SDK。尝试将 “目标SDK” 和 “最小SDK” 设置为一个较新且通用的版本例如目标SDK 34最小SDK 21。问题2游戏在手机上启动后立刻闪退Logcat中有No implementation found for ...或ClassNotFoundException。可能原因插件根本没有被打包进APK。这是最典型的安装失败症状。排查确认插件文件.aar等确实放在了res://addons/admob/android/bin/下。确认在项目设置的导出 - Android中勾选了“使用自定义构建”。尝试完全删除项目根目录下的.godot/缓存文件夹关闭Godot后操作然后重新打开项目并导出。问题3广告位一片空白Logcat显示Failed to load ad: Error Code 3。可能原因广告单元ID无效或未激活。排查检查代码中的广告单元ID是否拼写正确。登录AdMob后台确认该广告单元状态是否为“已启用”。新创建的广告单元可能需要等待一段时间最多24小时才能开始投放广告。确保你的AdMob应用关联了有效的付款资料。问题4激励视频看完了rewarded_earned_reward信号没有触发。可能原因玩家没有看完广告或者广告提供商没有发送奖励验证回调。排查确保你连接了rewarded_earned_reward信号。使用Google的测试广告单元ID进行测试它们的行为是确定性的看完一定会触发奖励。绝对不要在rewarded_closed信号里发奖励必须在rewarded_earned_reward里发。问题5在编辑器里运行游戏调用广告相关代码导致脚本错误。原因这是正常的AdMob插件只在导出的Android或iOS平台上有效。在编辑器或桌面平台运行时Engine.has_singleton(AdMob)会返回false。解决在你的广告管理代码中一定要做平台判断。func _ready(): if OS.get_name() Android or OS.get_name() iOS: # 初始化广告代码 _initialize_ads() else: # 在桌面或编辑器环境下可以模拟广告行为或直接跳过 print(Running on desktop, AdMob disabled.)集成第三方插件总会遇到各种小问题耐心查看日志仔细核对每一步大部分问题都能解决。这个Godot AdMob插件经过多年发展社区资料相对丰富遇到棘手问题时去GitHub的Issues页面或者Godot社区论坛搜索一下很可能已经有人提供了答案。
返回列表