├── .gitignore
├── LICENSE
├── README.md
├── admob
├── SCsub
├── android
│ ├── AndroidManifestChunk.xml
│ └── GodotAdMob.java
├── config-firebase.py
├── config.py
├── ios
│ ├── lib
│ │ ├── put_GoogleAppMeasurement.framework_here
│ │ ├── put_GoogleMobileAds.framework_here
│ │ ├── put_GoogleUtilities.xcframework_here
│ │ ├── put_PromisesObjC.xcframework_here
│ │ └── put_nanopb.xcframework_here
│ └── src
│ │ ├── AdmobBanner.h
│ │ ├── AdmobBanner.mm
│ │ ├── AdmobInterstitial.h
│ │ ├── AdmobInterstitial.mm
│ │ ├── AdmobRewarded.h
│ │ ├── AdmobRewarded.mm
│ │ ├── godotAdmob.h
│ │ └── godotAdmob.mm
├── register_types.cpp
└── register_types.h
├── examples
├── README.md
├── godot-2
│ ├── engine.cfg
│ ├── icon.png
│ ├── main.gd
│ └── main.tscn
└── godot-3
│ ├── icon.png
│ ├── main.gd
│ ├── main.tscn
│ └── project.godot
├── issue_template.md
└── templates
├── README.md
├── android_debug.apk
└── android_release.apk
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | .DS_Store
3 | *.import
4 | .import
5 | *.o
6 | *.d
7 | *.framework
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Javier López Úbeda
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AdMob
2 | =====
3 | This is the AdMob module for Godot Engine (https://github.com/okamstudio/godot)
4 | - Android & iOS
5 | - Banner
6 | - Interstitial
7 | - Rewarded Video
8 |
9 | How to use
10 | ----------
11 |
12 | ### Android
13 | To use this module you'll need a custom template for Android. You can build it by yourself or download a precompiled one.
14 | Another option available for Godot 3.2+ is the [new Android plugin system](https://godotengine.org/article/godot-3-2-will-get-new-android-plugin-system), much easier to use (no recompilation needed). You can find a port of this module using this system [here](https://github.com/Shin-NiL/Godot-Android-Admob-Plugin).
15 |
16 | #### Compiling the template (First Option)
17 | This is harder, but you'll have more control over the building process. You can, for example, include any other module you want.
18 | For that, do the following steps:
19 | - Clone or download this repository.
20 | - Clone or download the [Godot Engine repository](https://github.com/godotengine/godot/). One important note here is that this must match the same version of the Godot editor you're using to develop your game.
21 | - Drop the "admob" directory inside the "modules" directory on the Godot source.
22 | - Recompile the android export template following the [official instructions](http://docs.godotengine.org/en/latest/reference/compiling_for_android.html#compiling-export-templates).
23 |
24 | #### Using precompiled templates (Second Option)
25 | If you don't want or can't build the template by yourself, you can find a precompiled template with this module [here](https://github.com/Shin-NiL/godot-custom-mobile-template). Go to the release tab and download the zip file.
26 |
27 | #### Export configuration
28 | - In your project goto Export > Target > Android:
29 | - Options:
30 | - Custom Package:
31 | - place the template apk you had compiled (or downloaded)
32 | - Permissions on:
33 | - Access Network State
34 | - Internet
35 | ### iOS
36 | - Drop the "admob" directory inside the "modules" directory on the Godot source;
37 | - Download and extract the [Google Mobile Ads SDK](https://developers.google.com/admob/ios/download) **(>= 7.60.0)** inside the directory "admob/ios/lib"; (If you are unable to download the version informed above, you can alternatively download it through [Cocoapods](https://cocoapods.org/#install) or [HERE](https://srv-file6.gofile.io/download/iLaAUS/GoogleMobileAds_framework_7_60_0.zip))
38 | - Follow the instructions provided by Google to [add the GADApplicationIdentifier to your Info.plist in XCode](https://developers.google.com/admob/ios/quick-start#update_your_infoplist). It is not necessary to add the frameworks to your XCode project, as they will be compiled and linked into the godot engine directly.
39 | - [Recompile the iOS export template](http://docs.godotengine.org/en/stable/development/compiling/compiling_for_ios.html). (If you get some error, check this [issue](https://github.com/kloder-games/godot-admob/issues/87))
40 |
41 | Configuring your game
42 | ---------------------
43 |
44 | ### Android
45 | To enable the module on Android, add the path to the module to the "modules" property on the [android] section of your ```engine.cfg``` file (Godot 2) or ```project.godot``` (Godot 3). It should look like this:
46 |
47 | [android]
48 | modules="org/godotengine/godot/GodotAdMob"
49 |
50 | If you have more separate by comma.
51 |
52 | ### iOS
53 | Follow the [exporting to iOS official documentation](http://docs.godotengine.org/en/stable/learning/workflow/export/exporting_for_ios.html).
54 |
55 | #### Godot 2
56 | Just make sure you're using your custom template (compiled in the previous step), for that rename it to "godot_opt.iphone" and replace the file with same name inside the Xcode project.
57 |
58 | #### Godot 3
59 | - Tutorial: https://www.youtube.com/watch?v=s5sNrOM3Oeo
60 | - Export your project from Godot, it'll create an Xcode project;
61 | - Copy the library (.a) you have compiled following the official documentation inside the exported Xcode project. You must override the 'your_project_name.a' file with this file.
62 | - Copy the following frameworks inside the exported Xcode project folder and link it using the "Link Binary with Libraries" option. In the case of xcframework, framework folder exists in the folder like `GoogleUtilities.xcframework/ios-armv7_arm64/GoogleUtilities.framework`;
63 | - GoogleMobileAds.framework
64 | - GoogleAppMeasurement.framework
65 | - GoogleUtilities.framework
66 | - PromisesObjC.framework
67 | - nanopb.framework
68 | - Add the following frameworks to the project:
69 | - StoreKit
70 | - GameKit
71 | - CoreVideo
72 | - AdSupport
73 | - MessageUI
74 | - CoreTelephony
75 | - CFNetwork
76 | - MobileCoreServices
77 | - SQLite (libsqlite3.0.tbd)
78 | - If you are using the version 7.65.0 >=, then also add this framework?
79 | - JavaScriptCore
80 | - Add the -ObjC linker flag to Other Linker Flags in your project's build settings:
81 | 
82 | - Update your GAMENAME-Info.plist file, add a GADApplicationIdentifier key with a string value of your [AdMob app ID](https://support.google.com/admob/answer/7356431):
83 | 
84 |
85 |
86 | API Reference (Android & iOS)
87 | -------------
88 |
89 | The following methods are available:
90 | ```python
91 |
92 | # Init AdMob
93 | # @param bool isReal Show real ad or test ad
94 | # @param int instance_id The instance id from Godot (get_instance_ID())
95 | init(isReal, instance_id)
96 |
97 | # Init AdMob with additional Content Rating parameters (Android and iOS)
98 | # @param bool isReal Show real ad or test ad
99 | # @param int instance_id The instance id from Godot (get_instance_ID())
100 | # @param boolean isForChildDirectedTreatment If isForChildDirectedTreatment is true, maxAdContetRating will be ignored (your maxAdContentRating would can not be other than "G")
101 | # @param boolean isPersonalized Ads are personalized by default, GDPR compliance within the European Economic Area may require you to disable personalization."
102 | # @param String maxAdContentRating It's value must be "G", "PG", "T" or "MA". If the rating of your app in Play Console and your config of maxAdContentRating in AdMob are not matched, your app can be banned by Google.
103 | initWithContentRating(isReal, instance_id, isForChildDirectedTreatment, isPersonalized, maxAdContentRating)
104 |
105 |
106 | # Banner Methods
107 | # --------------
108 |
109 | # Load Banner Ads (and show inmediatly)
110 | # @param String id The banner unit id
111 | # @param boolean isTop Show the banner on top or bottom
112 | loadBanner(id, isTop)
113 |
114 | # Show the banner
115 | showBanner()
116 |
117 | # Hide the banner
118 | hideBanner()
119 |
120 | # Resize the banner (when orientation change for example)
121 | resize()
122 |
123 | # Get the Banner width
124 | # @return int Banner width
125 | getBannerWidth()
126 |
127 | # Get the Banner height
128 | # @return int Banner height
129 | getBannerHeight()
130 |
131 | # Callback on ad loaded (Banner)
132 | _on_admob_ad_loaded()
133 |
134 | # Callback on ad network error (Banner)
135 | _on_admob_network_error()
136 |
137 | # Callback for banner on ad failed to load (other than network error)
138 | _on_admob_banner_failed_to_load()
139 |
140 | # Interstitial Methods
141 | # --------------------
142 |
143 | # Load Interstitial Ads
144 | # @param String id The interstitial unit id
145 | loadInterstitial(id)
146 |
147 | # Show the interstitial ad
148 | showInterstitial()
149 |
150 | # Callback for interstitial ad fail on load
151 | _on_interstitial_not_loaded()
152 |
153 | # Callback for interstitial loaded
154 | _on_interstitial_loaded
155 |
156 | # Callback for insterstitial ad close action
157 | _on_interstitial_close()
158 |
159 | # Rewarded Videos Methods
160 | # -----------------------
161 |
162 | # Load rewarded videos ads
163 | # @param String id The rewarded video unit id
164 | loadRewardedVideo(id)
165 |
166 | # Show the rewarded video ad
167 | showRewardedVideo()
168 |
169 | # Callback for rewarded video ad left application
170 | _on_rewarded_video_ad_left_application()
171 |
172 | # Callback for rewarded video ad closed
173 | _on_rewarded_video_ad_closed()
174 |
175 | # Callback for rewarded video ad failed to load
176 | # @param int errorCode the code of error
177 | _on_rewarded_video_ad_failed_to_load(errorCode)
178 |
179 | # Callback for rewarded video ad loaded
180 | _on_rewarded_video_ad_loaded()
181 |
182 | # Callback for rewarded video ad opened
183 | _on_rewarded_video_ad_opened()
184 |
185 | # Callback for rewarded video ad reward user
186 | # @param String currency The reward item description, ex: coin
187 | # @param int amount The reward item amount
188 | _on_rewarded(currency, amount)
189 |
190 | # Callback for rewarded video ad started do play
191 | _on_rewarded_video_started()
192 | ```
193 |
194 | Known Issues
195 | --------------
196 | * You can't use Rewarded Video and any other ad type (Banner and/or Interstitial) at same time on iOS or your app will crash with the error ```Multiple locks on web thread not allowed``` when the Reward is closed. To fix this, we need help from an iOS developer as I don't have any Apple hardware to do it by myself. You can see more details about this issue [here](https://github.com/kloder-games/godot-admob/issues/53). You can find a workaround for this issue [here](https://github.com/kloder-games/godot-admob/issues/53#issuecomment-501540139).
197 |
198 |
199 | Troubleshooting
200 | --------------
201 |
202 | * First of all, please make sure you're able to compile the custom template without the Admob module, this way we can isolate the cause of the issue.
203 |
204 | * Using the Xcode debug console for iOS and logcat for Android is the best way to troubleshoot most issues. You can filter Godot only messages with logcat using the command: ```adb logcat -s godot```
205 |
206 | * _ERROR_CODE_NO_FILL_ is a common issue with Admob, but out of the scope to this module. Here's the description on the API page: [ERROR_CODE_NO_FILL: The ad request was successful, but no ad was returned due to lack of ad inventory.](https://developers.google.com/android/reference/com/google/android/gms/ads/AdRequest.html#ERROR_CODE_NO_FILL)
207 |
208 | * If you're getting the error ```Undefined symbols for architecture armv7``` compiling for iOS, you should try open up the project in xcode, go to "General" tab, remove "GoogleMobileAds.framework" from frameworks, then re-add it. Should build then. Also, make sure you have directory godot/modules/admob/ios/lib added to framework search path (“Build Settings”). More info [here](https://github.com/kloder-games/godot-admob/issues/90#issuecomment-501608259).
209 |
210 | References
211 | -------------
212 | Based on the work of:
213 | * https://github.com/Mavhod/GodotAdmob
214 |
215 | License
216 | -------------
217 | MIT license
218 |
--------------------------------------------------------------------------------
/admob/SCsub:
--------------------------------------------------------------------------------
1 |
2 | Import('env')
3 |
4 | sources = [
5 | 'register_types.cpp',
6 | 'ios/src/godotAdmob.mm',
7 | 'ios/src/AdmobBanner.mm',
8 | 'ios/src/AdmobInterstitial.mm',
9 | 'ios/src/AdmobRewarded.mm'
10 | ]
11 |
12 | if (env["platform"] == "iphone"):
13 | env.add_source_files(env.modules_sources, sources)
14 |
15 |
--------------------------------------------------------------------------------
/admob/android/AndroidManifestChunk.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/admob/android/GodotAdMob.java:
--------------------------------------------------------------------------------
1 | package org.godotengine.godot;
2 |
3 | import com.google.android.gms.ads.*;
4 |
5 |
6 | import java.security.MessageDigest;
7 | import java.security.NoSuchAlgorithmException;
8 |
9 | import android.app.Activity;
10 | import android.widget.FrameLayout;
11 | import android.view.ViewGroup.LayoutParams;
12 | import android.provider.Settings;
13 | import android.graphics.Color;
14 | import android.util.Log;
15 | import java.util.Locale;
16 | import android.view.Gravity;
17 | import android.view.View;
18 | import android.os.Bundle;
19 |
20 | import com.google.android.gms.ads.AdRequest;
21 | import com.google.android.gms.ads.MobileAds;
22 | import com.google.ads.mediation.admob.AdMobAdapter;
23 | import com.google.android.gms.ads.reward.RewardItem;
24 | import com.google.android.gms.ads.reward.RewardedVideoAd;
25 | import com.google.android.gms.ads.reward.RewardedVideoAdListener;
26 |
27 | public class GodotAdMob extends Godot.SingletonBase
28 | {
29 |
30 | private Activity activity = null; // The main activity of the game
31 | private int instance_id = 0;
32 |
33 | private InterstitialAd interstitialAd = null; // Interstitial object
34 | private AdView adView = null; // Banner view
35 |
36 | private boolean isReal = false; // Store if is real or not
37 | private boolean isForChildDirectedTreatment = false; // Store if is children directed treatment desired
38 | private boolean isPersonalized = true; // ads are personalized by default, GDPR compliance within the European Economic Area may require you to disable personalization.
39 | private String maxAdContentRating = ""; // Store maxAdContentRating ("G", "PG", "T" or "MA")
40 | private Bundle extras = null;
41 |
42 |
43 | private FrameLayout layout = null; // Store the layout
44 | private FrameLayout.LayoutParams adParams = null; // Store the layout params
45 |
46 | private RewardedVideoAd rewardedVideoAd = null; // Rewarded Video object
47 |
48 | /* Init
49 | * ********************************************************************** */
50 |
51 | /**
52 | * Prepare for work with AdMob
53 | * @param boolean isReal Tell if the enviroment is for real or test
54 | * @param int gdscript instance id
55 | */
56 | public void init(boolean isReal, int instance_id) {
57 | this.initWithContentRating(isReal, instance_id, false, true, "");
58 | }
59 | /**
60 | * Init with content rating additional options
61 | * @param boolean isReal Tell if the enviroment is for real or test
62 | * @param int gdscript instance id
63 | * @param boolean isPersonalized If ads should be personalized or not.
64 | * GDPR compliance within the European Economic Area requires that you
65 | * disable ad personalization if the user does not wish to opt into
66 | * ad personalization.
67 | * @param String maxAdContentRating must be "G", "PG", "T" or "MA"
68 | */
69 | public void initWithContentRating(boolean isReal, int instance_id, boolean isForChildDirectedTreatment, boolean isPersonalized, String maxAdContentRating)
70 | {
71 | this.isReal = isReal;
72 | this.instance_id = instance_id;
73 | this.isForChildDirectedTreatment = isForChildDirectedTreatment;
74 | this.isPersonalized = isPersonalized;
75 | this.maxAdContentRating = maxAdContentRating;
76 | if (maxAdContentRating != null && maxAdContentRating != "")
77 | {
78 | extras = new Bundle();
79 | extras.putString("max_ad_content_rating", maxAdContentRating);
80 | }
81 | if(!isPersonalized)
82 | {
83 | // https://developers.google.com/admob/android/eu-consent#forward_consent_to_the_google_mobile_ads_sdk
84 | if(extras == null)
85 | {
86 | extras = new Bundle();
87 | }
88 | extras.putString("npa", "1");
89 | }
90 | Log.d("godot", "AdMob: init with content rating options");
91 | }
92 |
93 |
94 |
95 | /**
96 | * Returns AdRequest object constructed considering the parameters set in constructor of this class.
97 | * @return AdRequest object
98 | */
99 | private AdRequest getAdRequest()
100 | {
101 | AdRequest.Builder adBuilder = new AdRequest.Builder();
102 | AdRequest adRequest;
103 | if (!this.isForChildDirectedTreatment && extras != null)
104 | {
105 | adBuilder.addNetworkExtrasBundle(AdMobAdapter.class, extras);
106 | }
107 | if (this.isForChildDirectedTreatment)
108 | {
109 | adBuilder.tagForChildDirectedTreatment(true);
110 | }
111 | if (!isReal) {
112 | adBuilder.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
113 | adBuilder.addTestDevice(getAdmobDeviceId());
114 | }
115 | adRequest = adBuilder.build();
116 | return adRequest;
117 | }
118 |
119 | /* Rewarded Video
120 | * ********************************************************************** */
121 | private void initRewardedVideo()
122 | {
123 | activity.runOnUiThread(new Runnable()
124 | {
125 | @Override public void run()
126 | {
127 | MobileAds.initialize(activity);
128 | rewardedVideoAd = MobileAds.getRewardedVideoAdInstance(activity);
129 | rewardedVideoAd.setRewardedVideoAdListener(new RewardedVideoAdListener()
130 | {
131 | @Override
132 | public void onRewardedVideoAdLeftApplication() {
133 | Log.w("godot", "AdMob: onRewardedVideoAdLeftApplication");
134 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_ad_left_application", new Object[] { });
135 | }
136 |
137 | @Override
138 | public void onRewardedVideoAdClosed() {
139 | Log.w("godot", "AdMob: onRewardedVideoAdClosed");
140 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_ad_closed", new Object[] { });
141 | }
142 |
143 | @Override
144 | public void onRewardedVideoAdFailedToLoad(int errorCode) {
145 | Log.w("godot", "AdMob: onRewardedVideoAdFailedToLoad. errorCode: " + errorCode);
146 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_ad_failed_to_load", new Object[] { errorCode });
147 | }
148 |
149 | @Override
150 | public void onRewardedVideoAdLoaded() {
151 | Log.w("godot", "AdMob: onRewardedVideoAdLoaded");
152 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_ad_loaded", new Object[] { });
153 | }
154 |
155 | @Override
156 | public void onRewardedVideoAdOpened() {
157 | Log.w("godot", "AdMob: onRewardedVideoAdOpened");
158 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_ad_opened", new Object[] { });
159 | }
160 |
161 | @Override
162 | public void onRewarded(RewardItem reward) {
163 | Log.w("godot", "AdMob: " + String.format(" onRewarded! currency: %s amount: %d", reward.getType(),
164 | reward.getAmount()));
165 | GodotLib.calldeferred(instance_id, "_on_rewarded", new Object[] { reward.getType(), reward.getAmount() });
166 | }
167 |
168 | @Override
169 | public void onRewardedVideoStarted() {
170 | Log.w("godot", "AdMob: onRewardedVideoStarted");
171 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_started", new Object[] { });
172 | }
173 |
174 | @Override
175 | public void onRewardedVideoCompleted() {
176 | Log.w("godot", "AdMob: onRewardedVideoCompleted");
177 | GodotLib.calldeferred(instance_id, "_on_rewarded_video_completed", new Object[] { });
178 | }
179 | });
180 |
181 | }
182 | });
183 |
184 | }
185 |
186 | /**
187 | * Load a Rewarded Video
188 | * @param String id AdMod Rewarded video ID
189 | */
190 | public void loadRewardedVideo(final String id) {
191 | activity.runOnUiThread(new Runnable()
192 | {
193 | @Override public void run()
194 | {
195 | if (rewardedVideoAd == null) {
196 | initRewardedVideo();
197 | }
198 |
199 | if (!rewardedVideoAd.isLoaded()) {
200 | rewardedVideoAd.loadAd(id, getAdRequest());
201 | }
202 | }
203 | });
204 | }
205 |
206 | /**
207 | * Show a Rewarded Video
208 | */
209 | public void showRewardedVideo() {
210 | activity.runOnUiThread(new Runnable()
211 | {
212 | @Override public void run()
213 | {
214 | if (rewardedVideoAd.isLoaded()) {
215 | rewardedVideoAd.show();
216 | }
217 | }
218 | });
219 | }
220 |
221 |
222 | /* Banner
223 | * ********************************************************************** */
224 |
225 | /**
226 | * Load a banner
227 | * @param String id AdMod Banner ID
228 | * @param boolean isOnTop To made the banner top or bottom
229 | */
230 | public void loadBanner(final String id, final boolean isOnTop)
231 | {
232 | activity.runOnUiThread(new Runnable()
233 | {
234 | @Override public void run()
235 | {
236 | layout = ((Godot) activity).layout;
237 | adParams = new FrameLayout.LayoutParams(
238 | FrameLayout.LayoutParams.MATCH_PARENT,
239 | FrameLayout.LayoutParams.WRAP_CONTENT
240 | );
241 | if(isOnTop) adParams.gravity = Gravity.TOP;
242 | else adParams.gravity = Gravity.BOTTOM;
243 |
244 | if (adView != null)
245 | {
246 | layout.removeView(adView); // Remove the old view
247 | }
248 |
249 | adView = new AdView(activity);
250 | adView.setAdUnitId(id);
251 |
252 | adView.setBackgroundColor(Color.TRANSPARENT);
253 |
254 | adView.setAdSize(AdSize.SMART_BANNER);
255 | adView.setAdListener(new AdListener()
256 | {
257 | @Override
258 | public void onAdLoaded() {
259 | Log.w("godot", "AdMob: onAdLoaded");
260 | GodotLib.calldeferred(instance_id, "_on_admob_ad_loaded", new Object[]{ });
261 | }
262 |
263 | @Override
264 | public void onAdFailedToLoad(int errorCode)
265 | {
266 | String str;
267 | String callbackFunctionName = "_on_admob_banner_failed_to_load";
268 | switch(errorCode) {
269 | case AdRequest.ERROR_CODE_INTERNAL_ERROR:
270 | str = "ERROR_CODE_INTERNAL_ERROR";
271 | break;
272 | case AdRequest.ERROR_CODE_INVALID_REQUEST:
273 | str = "ERROR_CODE_INVALID_REQUEST";
274 | break;
275 | case AdRequest.ERROR_CODE_NETWORK_ERROR:
276 | str = "ERROR_CODE_NETWORK_ERROR";
277 | callbackFunctionName = "_on_admob_network_error";
278 | break;
279 | case AdRequest.ERROR_CODE_NO_FILL:
280 | str = "ERROR_CODE_NO_FILL";
281 | break;
282 | default:
283 | str = "Code: " + errorCode;
284 | break;
285 | }
286 | Log.w("godot", "AdMob: onAdFailedToLoad -> " + str);
287 | Log.w("godot", "AdMob: callbackfunction -> " + callbackFunctionName);
288 |
289 | GodotLib.calldeferred(instance_id, callbackFunctionName, new Object[]{ });
290 | }
291 | });
292 | layout.addView(adView, adParams);
293 |
294 | // Request
295 | adView.loadAd(getAdRequest());
296 | }
297 | });
298 | }
299 |
300 | /**
301 | * Show the banner
302 | */
303 | public void showBanner()
304 | {
305 | activity.runOnUiThread(new Runnable()
306 | {
307 | @Override public void run()
308 | {
309 | if (adView.getVisibility() == View.VISIBLE) return;
310 | adView.setVisibility(View.VISIBLE);
311 | adView.resume();
312 | Log.d("godot", "AdMob: Show Banner");
313 | }
314 | });
315 | }
316 |
317 | /**
318 | * Resize the banner
319 | *
320 | */
321 | public void resize()
322 | {
323 | activity.runOnUiThread(new Runnable()
324 | {
325 | @Override public void run()
326 | {
327 | if (layout == null || adView == null || adParams == null)
328 | {
329 | return;
330 | }
331 |
332 | layout.removeView(adView); // Remove the old view
333 |
334 | // Extract params
335 |
336 | int gravity = adParams.gravity;
337 | FrameLayout layout = ((Godot)activity).layout;
338 | adParams = new FrameLayout.LayoutParams(
339 | FrameLayout.LayoutParams.MATCH_PARENT,
340 | FrameLayout.LayoutParams.WRAP_CONTENT
341 | );
342 | adParams.gravity = gravity;
343 | AdListener adListener = adView.getAdListener();
344 | String id = adView.getAdUnitId();
345 |
346 | // Create new view & set old params
347 | adView = new AdView(activity);
348 | adView.setAdUnitId(id);
349 | adView.setBackgroundColor(Color.TRANSPARENT);
350 | adView.setAdSize(AdSize.SMART_BANNER);
351 | adView.setAdListener(adListener);
352 |
353 | // Add to layout and load ad
354 | layout.addView(adView, adParams);
355 |
356 | // Request
357 | adView.loadAd(getAdRequest());
358 |
359 | Log.d("godot", "AdMob: Banner Resized");
360 | }
361 | });
362 | }
363 |
364 |
365 |
366 |
367 | /**
368 | * Hide the banner
369 | */
370 | public void hideBanner()
371 | {
372 | activity.runOnUiThread(new Runnable()
373 | {
374 | @Override public void run()
375 | {
376 | if (adView.getVisibility() == View.GONE) return;
377 | adView.setVisibility(View.GONE);
378 | adView.pause();
379 | Log.d("godot", "AdMob: Hide Banner");
380 | }
381 | });
382 | }
383 |
384 | /**
385 | * Get the banner width
386 | * @return int Banner width
387 | */
388 | public int getBannerWidth()
389 | {
390 | return AdSize.SMART_BANNER.getWidthInPixels(activity);
391 | }
392 |
393 | /**
394 | * Get the banner height
395 | * @return int Banner height
396 | */
397 | public int getBannerHeight()
398 | {
399 | return AdSize.SMART_BANNER.getHeightInPixels(activity);
400 | }
401 |
402 | /* Interstitial
403 | * ********************************************************************** */
404 |
405 | /**
406 | * Load a interstitial
407 | * @param String id AdMod Interstitial ID
408 | */
409 | public void loadInterstitial(final String id)
410 | {
411 | activity.runOnUiThread(new Runnable()
412 | {
413 | @Override public void run()
414 | {
415 | interstitialAd = new InterstitialAd(activity);
416 | interstitialAd.setAdUnitId(id);
417 | interstitialAd.setAdListener(new AdListener()
418 | {
419 | @Override
420 | public void onAdLoaded() {
421 | Log.w("godot", "AdMob: onAdLoaded");
422 | GodotLib.calldeferred(instance_id, "_on_interstitial_loaded", new Object[] { });
423 | }
424 |
425 | @Override
426 | public void onAdFailedToLoad(int errorCode) {
427 | Log.w("godot", "AdMob: onAdFailedToLoad(int errorCode) - error code: " + Integer.toString(errorCode));
428 | Log.w("godot", "AdMob: _on_interstitial_not_loaded");
429 | GodotLib.calldeferred(instance_id, "_on_interstitial_not_loaded", new Object[] { });
430 | }
431 |
432 | @Override
433 | public void onAdOpened() {
434 | Log.w("godot", "AdMob: onAdOpened()");
435 | }
436 |
437 | @Override
438 | public void onAdLeftApplication() {
439 | Log.w("godot", "AdMob: onAdLeftApplication()");
440 | }
441 |
442 | @Override
443 | public void onAdClosed() {
444 | GodotLib.calldeferred(instance_id, "_on_interstitial_close", new Object[] { });
445 | Log.w("godot", "AdMob: onAdClosed");
446 | }
447 | });
448 |
449 |
450 |
451 | interstitialAd.loadAd(getAdRequest());
452 | }
453 | });
454 | }
455 |
456 | /**
457 | * Show the interstitial
458 | */
459 | public void showInterstitial()
460 | {
461 | activity.runOnUiThread(new Runnable()
462 | {
463 | @Override public void run()
464 | {
465 | if (interstitialAd.isLoaded()) {
466 | interstitialAd.show();
467 | } else {
468 | Log.w("w", "AdMob: showInterstitial - interstitial not loaded");
469 | }
470 | }
471 | });
472 | }
473 |
474 | /* Utils
475 | * ********************************************************************** */
476 |
477 | /**
478 | * Generate MD5 for the deviceID
479 | * @param String s The string to generate de MD5
480 | * @return String The MD5 generated
481 | */
482 | private String md5(final String s)
483 | {
484 | try {
485 | // Create MD5 Hash
486 | MessageDigest digest = MessageDigest.getInstance("MD5");
487 | digest.update(s.getBytes());
488 | byte messageDigest[] = digest.digest();
489 |
490 | // Create Hex String
491 | StringBuffer hexString = new StringBuffer();
492 | for (int i=0; i
2 | #import "app_delegate.h"
3 |
4 | #define BANNER_ENABLE_DELAY 5
5 |
6 | @interface AdmobBanner: NSObject {
7 | GADBannerView *bannerView;
8 | bool initialized;
9 | bool isReal;
10 | bool isOnTop;
11 | int instanceId;
12 | NSString *adUnitId;
13 | ViewController *rootController;
14 | }
15 |
16 | - (void)initialize:(BOOL)is_real: (int)instance_id;
17 | - (void)loadBanner:(NSString*)bannerId :(BOOL)is_on_top;
18 | - (void)showBanner;
19 | - (void)hideBanner;
20 | - (void)disableBanner;
21 | - (void)enableBanner;
22 | - (void)resize;
23 | - (int)getBannerWidth;
24 | - (int)getBannerHeight;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/admob/ios/src/AdmobBanner.mm:
--------------------------------------------------------------------------------
1 | #import "AdmobBanner.h"
2 | #include "reference.h"
3 |
4 | @implementation AdmobBanner
5 |
6 | - (void)dealloc {
7 | bannerView.delegate = nil;
8 | [bannerView release];
9 | [super dealloc];
10 | }
11 |
12 | - (void)initialize:(BOOL)is_real: (int)instance_id {
13 | isReal = is_real;
14 | initialized = true;
15 | instanceId = instance_id;
16 | rootController = [AppDelegate getViewController];
17 | }
18 |
19 |
20 | - (void) loadBanner:(NSString*)bannerId: (BOOL)is_on_top {
21 | NSLog(@"Calling loadBanner");
22 |
23 | isOnTop = is_on_top;
24 |
25 | if (!initialized || (!bannerId.length)) {
26 | return;
27 | }
28 | else{
29 | NSLog(@"banner will load with the banner id");
30 | NSLog(bannerId);
31 | }
32 |
33 |
34 | UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
35 |
36 | if (bannerView == nil) {
37 | if (orientation == 0 || orientation == UIInterfaceOrientationPortrait) { //portrait
38 | bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
39 | }
40 | else { //landscape
41 | bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerLandscape];
42 | }
43 |
44 | if(!isReal) {
45 | bannerView.adUnitID = @"ca-app-pub-3940256099942544/2934735716";
46 | }
47 | else {
48 | bannerView.adUnitID = bannerId;
49 | }
50 |
51 | bannerView.delegate = self;
52 | bannerView.rootViewController = rootController;
53 |
54 |
55 | [self addBannerViewToView:bannerView:is_on_top];
56 | }
57 |
58 | GADRequest *request = [GADRequest request];
59 | [bannerView loadRequest:request];
60 |
61 | }
62 |
63 |
64 | - (void)addBannerViewToView:(UIView *_Nonnull)bannerView: (BOOL)is_on_top{
65 | bannerView.translatesAutoresizingMaskIntoConstraints = NO;
66 | [rootController.view addSubview:bannerView];
67 | if (@available(ios 11.0, *)) {
68 | [self positionBannerViewFullWidthAtSafeArea:bannerView:is_on_top];
69 | } else {
70 | [self positionBannerViewFullWidthAtView:bannerView:is_on_top];
71 | }
72 | }
73 |
74 |
75 |
76 | - (void)positionBannerViewFullWidthAtSafeArea:(UIView *_Nonnull)bannerView: (BOOL)is_on_top NS_AVAILABLE_IOS(11.0) {
77 | UILayoutGuide *guide = rootController.view.safeAreaLayoutGuide;
78 |
79 | if (is_on_top) {
80 | [NSLayoutConstraint activateConstraints:@[
81 | [guide.leftAnchor constraintEqualToAnchor:bannerView.leftAnchor],
82 | [guide.rightAnchor constraintEqualToAnchor:bannerView.rightAnchor],
83 | [guide.topAnchor constraintEqualToAnchor:bannerView.topAnchor]
84 | ]];
85 | } else {
86 | [NSLayoutConstraint activateConstraints:@[
87 | [guide.leftAnchor constraintEqualToAnchor:bannerView.leftAnchor],
88 | [guide.rightAnchor constraintEqualToAnchor:bannerView.rightAnchor],
89 | [guide.bottomAnchor constraintEqualToAnchor:bannerView.bottomAnchor]
90 | ]];
91 | }
92 | }
93 |
94 |
95 | - (void)positionBannerViewFullWidthAtView:(UIView *_Nonnull)bannerView: (BOOL)is_on_top {
96 |
97 | [rootController.view addConstraint:[NSLayoutConstraint constraintWithItem:bannerView
98 | attribute:NSLayoutAttributeLeading
99 | relatedBy:NSLayoutRelationEqual
100 | toItem:rootController.view
101 | attribute:NSLayoutAttributeLeading
102 | multiplier:1
103 | constant:0]];
104 | [rootController.view addConstraint:[NSLayoutConstraint constraintWithItem:bannerView
105 | attribute:NSLayoutAttributeTrailing
106 | relatedBy:NSLayoutRelationEqual
107 | toItem:rootController.view
108 | attribute:NSLayoutAttributeTrailing
109 | multiplier:1
110 | constant:0]];
111 |
112 | if (is_on_top) {
113 | [rootController.view addConstraint:[NSLayoutConstraint constraintWithItem:bannerView
114 | attribute:NSLayoutAttributeTop
115 | relatedBy:NSLayoutRelationEqual
116 | toItem:rootController.topLayoutGuide
117 | attribute:NSLayoutAttributeTop
118 | multiplier:1
119 | constant:0]];
120 |
121 | } else {
122 | [rootController.view addConstraint:[NSLayoutConstraint constraintWithItem:bannerView
123 | attribute:NSLayoutAttributeBottom
124 | relatedBy:NSLayoutRelationEqual
125 | toItem:rootController.bottomLayoutGuide
126 | attribute:NSLayoutAttributeTop
127 | multiplier:1
128 | constant:0]];
129 | }
130 | }
131 |
132 | - (void)showBanner {
133 | NSLog(@"Calling showBanner");
134 |
135 | if (bannerView == nil || !initialized) {
136 | return;
137 | }
138 |
139 | [bannerView setHidden:NO];
140 | }
141 |
142 | - (void) hideBanner {
143 | NSLog(@"Calling hideBanner");
144 | if (bannerView == nil || !initialized) {
145 | return;
146 | }
147 | [bannerView setHidden:YES];
148 | }
149 | - (void) disableBanner {
150 | NSLog(@"Calling disableBanner");
151 | if (bannerView == nil || !initialized) {
152 | return;
153 | }
154 | [bannerView setHidden:YES];
155 | [bannerView removeFromSuperview];
156 | adUnitId = bannerView.adUnitID;
157 | bannerView = nil;
158 | }
159 |
160 | - (void) enableBanner {
161 | NSLog(@"Calling enableBanner");
162 | if (!initialized) {
163 | return;
164 | }
165 |
166 | if (bannerView == nil) {
167 | [self loadBanner:adUnitId:isOnTop];
168 | }
169 | if (bannerView != nil){
170 | [bannerView setHidden:NO];
171 | }
172 | }
173 |
174 | - (void) resize {
175 | NSLog(@"Calling resize banner");
176 | if (bannerView != nil){
177 | NSString* currentAdUnitId = bannerView.adUnitID;
178 | [self hideBanner];
179 | [bannerView removeFromSuperview];
180 | bannerView = nil;
181 | [self loadBanner:currentAdUnitId:isOnTop];
182 | NSLog(@"Resize called sucessful");
183 | }
184 | else{
185 | NSLog(@"Resize banner doesnt happen, because was not loaded");
186 | }
187 | }
188 |
189 | - (int) getBannerWidth {
190 | return bannerView.bounds.size.width * [UIScreen mainScreen].scale;
191 | }
192 |
193 | - (int) getBannerHeight {
194 | return bannerView.bounds.size.height * [UIScreen mainScreen].scale;
195 | }
196 |
197 |
198 |
199 | /// Tells the delegate an ad request loaded an ad.
200 | - (void)adViewDidReceiveAd:(GADBannerView *)adView {
201 | NSLog(@"adViewDidReceiveAd");
202 | Object *obj = ObjectDB::get_instance(instanceId);
203 | obj->call_deferred("_on_admob_ad_loaded");
204 | }
205 |
206 | /// Tells the delegate an ad request failed.
207 | - (void)adView:(GADBannerView *)adView
208 | didFailToReceiveAdWithError:(GADRequestError *)error {
209 | NSLog(@"adView:didFailToReceiveAdWithError: %@", [error localizedDescription]);
210 | Object *obj = ObjectDB::get_instance(instanceId);
211 | obj->call_deferred("_on_admob_network_error");
212 | }
213 |
214 | /// Tells the delegate that a full screen view will be presented in response
215 | /// to the user clicking on an ad.
216 | - (void)adViewWillPresentScreen:(GADBannerView *)adView {
217 | NSLog(@"adViewWillPresentScreen");
218 | }
219 |
220 | /// Tells the delegate that the full screen view will be dismissed.
221 | - (void)adViewWillDismissScreen:(GADBannerView *)adView {
222 | NSLog(@"adViewWillDismissScreen");
223 | }
224 |
225 | /// Tells the delegate that the full screen view has been dismissed.
226 | - (void)adViewDidDismissScreen:(GADBannerView *)adView {
227 | NSLog(@"adViewDidDismissScreen");
228 | }
229 |
230 | /// Tells the delegate that a user click will open another app (such as
231 | /// the App Store), backgrounding the current app.
232 | - (void)adViewWillLeaveApplication:(GADBannerView *)adView {
233 | NSLog(@"adViewWillLeaveApplication");
234 | }
235 |
236 |
237 | @end
--------------------------------------------------------------------------------
/admob/ios/src/AdmobInterstitial.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "app_delegate.h"
3 | #import "AdmobBanner.h"
4 |
5 | @interface AdmobInterstitial: NSObject {
6 | AdmobBanner *admobBanner;
7 | GADInterstitial *interstitial;
8 | bool initialized;
9 | bool isReal;
10 | int instanceId;
11 | ViewController *rootController;
12 | }
13 |
14 | - (void)initialize:(BOOL)is_real: (int)instance_id: (AdmobBanner *)banner;
15 | - (void)loadInterstitial:(NSString*)interstitialId;
16 | - (void)showInterstitial;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/admob/ios/src/AdmobInterstitial.mm:
--------------------------------------------------------------------------------
1 | #import "AdmobInterstitial.h"
2 | #include "reference.h"
3 |
4 |
5 | @implementation AdmobInterstitial
6 |
7 | - (void)dealloc {
8 | interstitial.delegate = nil;
9 | [interstitial release];
10 | [super dealloc];
11 | }
12 |
13 | - (void)initialize:(BOOL)is_real: (int)instance_id: (AdmobBanner *)admob_banner {
14 | isReal = is_real;
15 | initialized = true;
16 | instanceId = instance_id;
17 | admobBanner = admob_banner;
18 | rootController = [AppDelegate getViewController];
19 | }
20 |
21 | - (void) loadInterstitial:(NSString*)interstitialId {
22 |
23 | NSLog(@"Calling loadInterstitial");
24 | //init
25 | if (!initialized) {
26 | return;
27 | }
28 |
29 | interstitial = nil;
30 | if(!isReal) {
31 | interstitial = [[GADInterstitial alloc]
32 | initWithAdUnitID:@"ca-app-pub-3940256099942544/4411468910"];
33 | }
34 | else {
35 | interstitial = [[GADInterstitial alloc] initWithAdUnitID:interstitialId];
36 | }
37 |
38 | interstitial.delegate = self;
39 |
40 |
41 | //load
42 | GADRequest *request = [GADRequest request];
43 | [interstitial loadRequest:request];
44 | }
45 |
46 | - (void) showInterstitial {
47 | NSLog(@"Calling showInterstitial");
48 | //show
49 |
50 | if (interstitial == nil || !initialized) {
51 | return;
52 | }
53 |
54 | if (interstitial.isReady) {
55 | [admobBanner disableBanner];
56 | [interstitial presentFromRootViewController:rootController];
57 | } else {
58 | NSLog(@"Interstitial Ad wasn't ready");
59 | }
60 |
61 |
62 | }
63 |
64 |
65 |
66 | /// Tells the delegate an ad request succeeded.
67 | - (void)interstitialDidReceiveAd:(GADInterstitial *)ad {
68 | NSLog(@"interstitialDidReceiveAd");
69 | Object *obj = ObjectDB::get_instance(instanceId);
70 | obj->call_deferred("_on_interstitial_loaded");
71 | }
72 |
73 | /// Tells the delegate an ad request failed.
74 | - (void)interstitial:(GADInterstitial *)ad
75 | didFailToReceiveAdWithError:(GADRequestError *)error {
76 | NSLog(@"interstitial:didFailToReceiveAdWithError: %@", [error localizedDescription]);
77 | Object *obj = ObjectDB::get_instance(instanceId);
78 | obj->call_deferred("_on_interstitial_not_loaded");
79 | }
80 |
81 | /// Tells the delegate that an interstitial will be presented.
82 | - (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
83 | NSLog(@"interstitialWillPresentScreen");
84 | }
85 |
86 | /// Tells the delegate the interstitial is to be animated off the screen.
87 | - (void)interstitialWillDismissScreen:(GADInterstitial *)ad {
88 | NSLog(@"interstitialWillDismissScreen");
89 | [self performSelector:@selector(bannerEnable) withObject:nil afterDelay:BANNER_ENABLE_DELAY];
90 | }
91 | - (void)bannerEnable{
92 | NSLog(@"banner enable call");
93 | [admobBanner enableBanner];
94 | }
95 |
96 | /// Tells the delegate the interstitial had been animated off the screen.
97 | - (void)interstitialDidDismissScreen:(GADInterstitial *)ad {
98 | NSLog(@"interstitialDidDismissScreen");
99 | Object *obj = ObjectDB::get_instance(instanceId);
100 | obj->call_deferred("_on_interstitial_close");
101 |
102 | }
103 |
104 | /// Tells the delegate that a user click will open another app
105 | /// (such as the App Store), backgrounding the current app.
106 | - (void)interstitialWillLeaveApplication:(GADInterstitial *)ad {
107 | NSLog(@"interstitialWillLeaveApplication");
108 | }
109 |
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/admob/ios/src/AdmobRewarded.h:
--------------------------------------------------------------------------------
1 | #import "app_delegate.h"
2 | #import
3 | #import "AdmobBanner.h"
4 |
5 | @interface AdmobRewarded: NSObject {
6 | AdmobBanner *admobBanner;
7 | bool initialized;
8 | bool isReal;
9 | int instanceId;
10 | ViewController *rootController;
11 | }
12 |
13 | - (void)initialize:(BOOL)is_real: (int)instance_id: (AdmobBanner *)banner;
14 | - (void)loadRewardedVideo:(NSString*)rewardedId;
15 | - (void)showRewardedVideo;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/admob/ios/src/AdmobRewarded.mm:
--------------------------------------------------------------------------------
1 | #import "AdmobRewarded.h"
2 | #import
3 | #import
4 | #include "reference.h"
5 |
6 |
7 | @implementation AdmobRewarded
8 |
9 |
10 | - (void)initialize:(BOOL)is_real: (int)instance_id: (AdmobBanner *)admob_banner {
11 | isReal = is_real;
12 | initialized = true;
13 | instanceId = instance_id;
14 | admobBanner = admob_banner;
15 | rootController = [AppDelegate getViewController];
16 | }
17 |
18 | - (void) loadRewardedVideo:(NSString*) rewardedId {
19 | NSLog(@"Calling loadRewardedVideo");
20 | //init
21 | if (!initialized) {
22 | return;
23 | }
24 |
25 | if(!isReal) {
26 | [[GADRewardBasedVideoAd sharedInstance] loadRequest:[GADRequest request]
27 | withAdUnitID:@"ca-app-pub-3940256099942544/1712485313"];
28 | }
29 | else {
30 | [[GADRewardBasedVideoAd sharedInstance] loadRequest:[GADRequest request] withAdUnitID:rewardedId];
31 | }
32 |
33 |
34 | [GADRewardBasedVideoAd sharedInstance].delegate = self;
35 |
36 | }
37 |
38 | - (void) showRewardedVideo {
39 | NSLog(@"Calling showRewardedVideo");
40 | //init
41 | if (!initialized) {
42 | return;
43 | }
44 |
45 | if ([[GADRewardBasedVideoAd sharedInstance] isReady]) {
46 | [admobBanner disableBanner];
47 | [[GADRewardBasedVideoAd sharedInstance] presentFromRootViewController:rootController];
48 | }
49 |
50 | }
51 |
52 |
53 | - (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd didRewardUserWithReward:(GADAdReward *)reward {
54 | NSString *rewardMessage = [NSString stringWithFormat:@"Reward received with currency %@ , amount %lf",
55 | reward.type, [reward.amount doubleValue]];
56 | NSLog(rewardMessage);
57 |
58 | Object *obj = ObjectDB::get_instance(instanceId);
59 | obj->call_deferred("_on_rewarded", [reward.type UTF8String], reward.amount.doubleValue);
60 |
61 | }
62 |
63 | - (void)rewardBasedVideoAdDidReceiveAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
64 | NSLog(@"Reward based video ad is received.");
65 | Object *obj = ObjectDB::get_instance(instanceId);
66 | obj->call_deferred("_on_rewarded_video_ad_loaded");
67 | }
68 |
69 | - (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
70 | NSLog(@"Opened reward based video ad.");
71 | Object *obj = ObjectDB::get_instance(instanceId);
72 | obj->call_deferred("_on_rewarded_video_ad_opened");
73 | }
74 |
75 | - (void)rewardBasedVideoAdDidStartPlaying:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
76 | NSLog(@"Reward based video ad started playing.");
77 | Object *obj = ObjectDB::get_instance(instanceId);
78 | obj->call_deferred("_on_rewarded_video_started");
79 | }
80 |
81 | - (void)rewardBasedVideoAdDidClose:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
82 | NSLog(@"Reward based video ad is closed.");
83 | NSLog(@"Enable Banner with delay:%d",BANNER_ENABLE_DELAY);
84 | [self performSelector:@selector(bannerEnable) withObject:nil afterDelay:BANNER_ENABLE_DELAY];
85 | Object *obj = ObjectDB::get_instance(instanceId);
86 | obj->call_deferred("_on_rewarded_video_ad_closed");
87 | }
88 | - (void)bannerEnable{
89 | NSLog(@"banner enable call");
90 | [admobBanner enableBanner];
91 | }
92 |
93 | - (void)rewardBasedVideoAdWillLeaveApplication:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
94 | NSLog(@"Reward based video ad will leave application.");
95 | Object *obj = ObjectDB::get_instance(instanceId);
96 | obj->call_deferred("_on_rewarded_video_ad_left_application");
97 | }
98 |
99 | - (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd didFailToLoadWithError:(NSError *)error {
100 | NSLog(@"Reward based video ad failed to load: %@ ", error.localizedDescription);
101 | Object *obj = ObjectDB::get_instance(instanceId);
102 | obj->call_deferred("_on_rewarded_video_ad_failed_to_load", (int)error.code);
103 | }
104 |
105 | - (void)rewardBasedVideoAdDidCompletePlaying:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
106 | NSLog(@"Reward based video ad has completed.");
107 | Object *obj = ObjectDB::get_instance(instanceId);
108 | obj->call_deferred("_on_rewarded_video_completed");
109 | }
110 |
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/admob/ios/src/godotAdmob.h:
--------------------------------------------------------------------------------
1 | #ifndef GODOT_ADMOB_H
2 | #define GODOT_ADMOB_H
3 |
4 | #include
5 |
6 | #include "reference.h"
7 |
8 |
9 | #ifdef __OBJC__
10 | @class AdmobBanner;
11 | typedef AdmobBanner *bannerPtr;
12 | @class AdmobInterstitial;
13 | typedef AdmobInterstitial *interstitialPtr;
14 | @class AdmobRewarded;
15 | typedef AdmobRewarded *rewardedPtr;
16 | #else
17 | typedef void *bannerPtr;
18 | typedef void *interstitialPtr;
19 | typedef void *rewardedPtr;
20 | #endif
21 |
22 |
23 |
24 | class GodotAdmob : public Reference {
25 |
26 | #if VERSION_MAJOR == 3
27 | GDCLASS(GodotAdmob, Reference);
28 | #else
29 | OBJ_TYPE(GodotAdmob, Reference);
30 | #endif
31 |
32 | bool initialized;
33 | static GodotAdmob *instance; //fix
34 |
35 | bannerPtr banner;
36 | interstitialPtr interstitial;
37 | rewardedPtr rewarded;
38 |
39 |
40 | protected:
41 | static void _bind_methods();
42 |
43 | public:
44 |
45 | void init(bool isReal, int instanceId);
46 | void initWithContentRating(bool isReal, int instanceId, bool child_directed, bool is_personalized, const String &max_ad_content_rate);
47 | void loadBanner(const String &bannerId, bool isOnTop);
48 | void showBanner();
49 | void hideBanner();
50 | void resize();
51 | int getBannerWidth();
52 | int getBannerHeight();
53 | void loadInterstitial(const String &interstitialId);
54 | void showInterstitial();
55 | void loadRewardedVideo(const String &rewardedId);
56 | void showRewardedVideo();
57 |
58 | GodotAdmob();
59 | ~GodotAdmob();
60 | };
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/admob/ios/src/godotAdmob.mm:
--------------------------------------------------------------------------------
1 | #include "godotAdmob.h"
2 | #import "app_delegate.h"
3 |
4 | #if VERSION_MAJOR == 3
5 | #define CLASS_DB ClassDB
6 | #else
7 | #define CLASS_DB ObjectTypeDB
8 | #endif
9 |
10 | GodotAdmob *GodotAdmob::instance = NULL; //<< INIT NULL VAR ON COMPILE TIME!
11 |
12 | GodotAdmob::GodotAdmob() {
13 | initialized = false;
14 | banner = NULL;
15 | interstitial = NULL;
16 | rewarded = NULL;
17 | //
18 | ERR_FAIL_COND(instance != NULL); //<< SUCCESS!!! FIRST
19 |
20 | instance = this;
21 | }
22 |
23 | GodotAdmob::~GodotAdmob() {
24 | if (initialized) {
25 | [banner release]; //free banner
26 | [interstitial release]; //free
27 | [rewarded release]; //free
28 | }
29 |
30 | if (instance == this) {
31 | instance = NULL;
32 | }
33 | }
34 |
35 | void GodotAdmob::init(bool isReal, int instanceId) {
36 | if (instance != this) {
37 | NSLog(@"GodotAdmob Module dublicate singleton");
38 | return;
39 | }
40 | if (initialized) {
41 | NSLog(@"GodotAdmob Module already initialized");
42 | return;
43 | }
44 |
45 | initialized = true;
46 |
47 | banner = [[AdmobBanner alloc] init];
48 | [banner initialize :isReal :instanceId];
49 |
50 | interstitial = [[AdmobInterstitial alloc] init];
51 | [interstitial initialize :isReal :instanceId :banner];
52 |
53 | rewarded = [[AdmobRewarded alloc] init];
54 | [rewarded initialize :isReal :instanceId :banner];
55 | }
56 |
57 | void GodotAdmob::initWithContentRating(bool isReal, int instanceId, bool child_directed, bool is_personalized, const String &max_ad_content_rate) {
58 | if (instance != this) {
59 | NSLog(@"GodotAdmob Module dublicate singleton");
60 | return;
61 | }
62 | if (initialized) {
63 | NSLog(@"GodotAdmob Module already initialized");
64 | return;
65 | }
66 |
67 | initialized = true;
68 |
69 | banner = [[AdmobBanner alloc] init];
70 | [banner initialize :isReal :instanceId];
71 |
72 | interstitial = [[AdmobInterstitial alloc] init];
73 | [interstitial initialize :isReal :instanceId :banner];
74 |
75 | rewarded = [[AdmobRewarded alloc] init];
76 | [rewarded initialize :isReal :instanceId :banner];
77 | }
78 |
79 | void GodotAdmob::loadBanner(const String &bannerId, bool isOnTop) {
80 | if (!initialized) {
81 | NSLog(@"GodotAdmob Module not initialized");
82 | return;
83 | }
84 |
85 | NSString *idStr = [NSString stringWithCString:bannerId.utf8().get_data() encoding: NSUTF8StringEncoding];
86 | [banner loadBanner:idStr :isOnTop];
87 |
88 | }
89 |
90 | void GodotAdmob::showBanner() {
91 | if (!initialized) {
92 | NSLog(@"GodotAdmob Module not initialized");
93 | return;
94 | }
95 |
96 | [banner showBanner];
97 | }
98 |
99 | void GodotAdmob::hideBanner() {
100 | if (!initialized) {
101 | NSLog(@"GodotAdmob Module not initialized");
102 | return;
103 | }
104 | [banner hideBanner];
105 | }
106 |
107 |
108 | void GodotAdmob::resize() {
109 | if (!initialized) {
110 | NSLog(@"GodotAdmob Module not initialized");
111 | return;
112 | }
113 | [banner resize];
114 | }
115 |
116 | int GodotAdmob::getBannerWidth() {
117 | if (!initialized) {
118 | NSLog(@"GodotAdmob Module not initialized");
119 | return 0;
120 | }
121 | return (uintptr_t)[banner getBannerWidth];
122 | }
123 |
124 | int GodotAdmob::getBannerHeight() {
125 | if (!initialized) {
126 | NSLog(@"GodotAdmob Module not initialized");
127 | return 0;
128 | }
129 | return (uintptr_t)[banner getBannerHeight];
130 | }
131 |
132 | void GodotAdmob::loadInterstitial(const String &interstitialId) {
133 | if (!initialized) {
134 | NSLog(@"GodotAdmob Module not initialized");
135 | return;
136 | }
137 |
138 | NSString *idStr = [NSString stringWithCString:interstitialId.utf8().get_data() encoding: NSUTF8StringEncoding];
139 | [interstitial loadInterstitial:idStr];
140 |
141 | }
142 |
143 | void GodotAdmob::showInterstitial() {
144 | if (!initialized) {
145 | NSLog(@"GodotAdmob Module not initialized");
146 | return;
147 | }
148 |
149 | [interstitial showInterstitial];
150 |
151 | }
152 |
153 | void GodotAdmob::loadRewardedVideo(const String &rewardedId) {
154 | //init
155 | if (!initialized) {
156 | NSLog(@"GodotAdmob Module not initialized");
157 | return;
158 | }
159 |
160 | NSString *idStr = [NSString stringWithCString:rewardedId.utf8().get_data() encoding: NSUTF8StringEncoding];
161 | [rewarded loadRewardedVideo: idStr];
162 |
163 | }
164 |
165 | void GodotAdmob::showRewardedVideo() {
166 | //show
167 | if (!initialized) {
168 | NSLog(@"GodotAdmob Module not initialized");
169 | return;
170 | }
171 |
172 | [rewarded showRewardedVideo];
173 | }
174 |
175 |
176 |
177 | void GodotAdmob::_bind_methods() {
178 | CLASS_DB::bind_method("init",&GodotAdmob::init);
179 | CLASS_DB::bind_method("initWithContentRating",&GodotAdmob::initWithContentRating);
180 | CLASS_DB::bind_method("loadBanner",&GodotAdmob::loadBanner);
181 | CLASS_DB::bind_method("showBanner",&GodotAdmob::showBanner);
182 | CLASS_DB::bind_method("hideBanner",&GodotAdmob::hideBanner);
183 | CLASS_DB::bind_method("loadInterstitial",&GodotAdmob::loadInterstitial);
184 | CLASS_DB::bind_method("showInterstitial",&GodotAdmob::showInterstitial);
185 | CLASS_DB::bind_method("loadRewardedVideo",&GodotAdmob::loadRewardedVideo);
186 | CLASS_DB::bind_method("showRewardedVideo",&GodotAdmob::showRewardedVideo);
187 | CLASS_DB::bind_method("resize",&GodotAdmob::resize);
188 | CLASS_DB::bind_method("getBannerWidth",&GodotAdmob::getBannerWidth);
189 | CLASS_DB::bind_method("getBannerHeight",&GodotAdmob::getBannerHeight);
190 | }
191 |
--------------------------------------------------------------------------------
/admob/register_types.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #if VERSION_MAJOR == 3
4 | #include
5 | #include
6 | #else
7 | #include "object_type_db.h"
8 | #include "core/globals.h"
9 | #endif
10 |
11 | #include "register_types.h"
12 | #include "ios/src/godotAdmob.h"
13 |
14 | void register_admob_types() {
15 | #if VERSION_MAJOR == 3
16 | Engine::get_singleton()->add_singleton(Engine::Singleton("AdMob", memnew(GodotAdmob)));
17 | #else
18 | Globals::get_singleton()->add_singleton(Globals::Singleton("AdMob", memnew(GodotAdmob)));
19 | #endif
20 | }
21 |
22 | void unregister_admob_types() {
23 | }
24 |
--------------------------------------------------------------------------------
/admob/register_types.h:
--------------------------------------------------------------------------------
1 | void register_admob_types();
2 | void unregister_admob_types();
3 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Examples of use for AdMob Module
2 |
3 | These examples show how to interact with the module.
4 |
5 | ## Usage
6 |
7 | For use these examples you must create an account on AdMob and create an app (or link with Google Play one).
8 |
9 | After that create a new Ad Unit ID and use in the example code.
10 |
11 |
--------------------------------------------------------------------------------
/examples/godot-2/engine.cfg:
--------------------------------------------------------------------------------
1 | [android]
2 |
3 | modules="org/godotengine/godot/GodotAdMob"
4 |
5 | [application]
6 |
7 | name="testAdmob"
8 | main_scene="res://main.tscn"
9 | icon="icon.png"
10 |
11 | [display]
12 |
13 | width=1024
14 | height=600
15 | stretch_mode="viewport"
16 | stretch_aspect="keep_height"
17 | orientation="sensor"
18 |
--------------------------------------------------------------------------------
/examples/godot-2/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kloder-games/godot-admob/f5996ed22dfab457d611bc1f4f32d6305de3dcd2/examples/godot-2/icon.png
--------------------------------------------------------------------------------
/examples/godot-2/main.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 | var admob = null
4 | var isReal = false
5 | var isTop = true
6 | var adBannerId = "ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX" # [Replace with your Ad Unit ID and delete this message.]
7 | var adInterstitialId = "ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX" # [Replace with your Ad Unit ID and delete this message.]
8 | var adRewardedId = "ca-app-pub-3940256099942544/5224354917" # [There is no testing option for rewarded videos, so you can use this id for testing]
9 |
10 | func _ready():
11 | if(Globals.has_singleton("AdMob")):
12 | admob = Globals.get_singleton("AdMob")
13 | admob.init(isReal, get_instance_ID())
14 | loadBanner()
15 | loadInterstitial()
16 | loadRewardedVideo()
17 |
18 | get_tree().connect("screen_resized", self, "onResize")
19 |
20 | # Loaders
21 |
22 | func loadBanner():
23 | if admob != null:
24 | admob.loadBanner(adBannerId, isTop)
25 |
26 | func loadInterstitial():
27 | if admob != null:
28 | admob.loadInterstitial(adInterstitialId)
29 |
30 | func loadRewardedVideo():
31 | if admob != null:
32 | admob.loadRewardedVideo(adRewardedId)
33 |
34 | # Events
35 |
36 | func _on_BtnBanner_toggled(pressed):
37 | if admob != null:
38 | if pressed: admob.showBanner()
39 | else: admob.hideBanner()
40 |
41 | func _on_BtnInterstitial_pressed():
42 | if admob != null:
43 | admob.showInterstitial()
44 |
45 | func _on_BtnRewardedVideo_pressed():
46 | if admob != null:
47 | admob.showRewardedVideo()
48 |
49 | func _on_admob_network_error():
50 | print("Network Error")
51 |
52 | func _on_admob_ad_loaded():
53 | print("Ad loaded success")
54 | get_node("CanvasLayer/BtnBanner").set_disabled(false)
55 |
56 | func _on_interstitial_not_loaded():
57 | print("Error: Interstitial not loaded")
58 |
59 | func _on_interstitial_loaded():
60 | print("Interstitial loaded")
61 | get_node("CanvasLayer/BtnInterstitial").set_disabled(false)
62 |
63 | func _on_interstitial_close():
64 | print("Interstitial closed")
65 | get_node("CanvasLayer/BtnInterstitial").set_disabled(true)
66 |
67 | func _on_rewarded_video_ad_loaded():
68 | print("Rewarded loaded success")
69 | get_node("CanvasLayer/BtnRewardedVideo").set_disabled(false)
70 |
71 | func _on_rewarded_video_ad_closed():
72 | print("Rewarded closed")
73 | get_node("CanvasLayer/BtnRewardedVideo").set_disabled(true)
74 | loadRewardedVideo()
75 |
76 | func _on_rewarded(currency, amount):
77 | print("Reward: " + currency + ", " + str(amount))
78 | get_node("CanvasLayer/LblRewarded").set_text("Reward: " + currency + ", " + str(amount))
79 |
80 | # Resize
81 |
82 | func onResize():
83 | if admob != null:
84 | admob.resize()
85 |
86 |
--------------------------------------------------------------------------------
/examples/godot-2/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=1]
2 |
3 | [ext_resource path="res://main.gd" type="Script" id=1]
4 |
5 | [node name="Node2D" type="Node2D"]
6 |
7 | script/script = ExtResource( 1 )
8 | __meta__ = {
9 | "__editor_plugin_screen__": "3D"
10 | }
11 |
12 | [node name="CanvasLayer" type="CanvasLayer" parent="."]
13 |
14 | layer = 1
15 | offset = Vector2( 0, 0 )
16 | rotation = 0.0
17 | scale = Vector2( 1, 1 )
18 |
19 | [node name="BtnBanner" type="Button" parent="CanvasLayer"]
20 |
21 | anchor/left = 3
22 | anchor/top = 3
23 | anchor/right = 3
24 | anchor/bottom = 3
25 | focus/ignore_mouse = false
26 | focus/stop_mouse = true
27 | size_flags/horizontal = 2
28 | size_flags/vertical = 2
29 | margin/left = 75.0
30 | margin/top = 80.0
31 | margin/right = -75.0
32 | margin/bottom = 5.0
33 | disabled = true
34 | toggle_mode = true
35 | is_pressed = true
36 | enabled_focus_mode = 2
37 | shortcut = null
38 | text = "Show/Hide Banner"
39 | flat = false
40 |
41 | [node name="BtnInterstitial" type="Button" parent="CanvasLayer"]
42 |
43 | anchor/left = 3
44 | anchor/top = 3
45 | anchor/right = 3
46 | anchor/bottom = 3
47 | focus/ignore_mouse = false
48 | focus/stop_mouse = true
49 | size_flags/horizontal = 2
50 | size_flags/vertical = 2
51 | margin/left = 75.0
52 | margin/top = -5.0
53 | margin/right = -75.0
54 | margin/bottom = -80.0
55 | disabled = true
56 | toggle_mode = false
57 | enabled_focus_mode = 2
58 | shortcut = null
59 | text = "Show Interstitial"
60 | flat = false
61 |
62 | [node name="BtnRewardedVideo" type="Button" parent="CanvasLayer"]
63 |
64 | anchor/left = 3
65 | anchor/top = 3
66 | anchor/right = 3
67 | anchor/bottom = 3
68 | focus/ignore_mouse = false
69 | focus/stop_mouse = true
70 | size_flags/horizontal = 2
71 | size_flags/vertical = 2
72 | margin/left = 75.0
73 | margin/top = -94.0
74 | margin/right = -75.0
75 | margin/bottom = -169.0
76 | disabled = true
77 | toggle_mode = false
78 | enabled_focus_mode = 2
79 | shortcut = null
80 | text = "Show Rewarded Video"
81 | flat = false
82 |
83 | [node name="LblRewarded" type="Label" parent="CanvasLayer"]
84 |
85 | focus/ignore_mouse = true
86 | focus/stop_mouse = true
87 | size_flags/horizontal = 2
88 | size_flags/vertical = 0
89 | margin/left = 0.0
90 | margin/top = 0.0
91 | margin/right = 1026.0
92 | margin/bottom = 32.0
93 | text = "REWARDED VIDEO RETURN"
94 | align = 1
95 | valign = 1
96 | percent_visible = 1.0
97 | lines_skipped = 0
98 | max_lines_visible = -1
99 |
100 | [connection signal="toggled" from="CanvasLayer/BtnBanner" to="." method="_on_BtnBanner_toggled"]
101 |
102 | [connection signal="pressed" from="CanvasLayer/BtnInterstitial" to="." method="_on_BtnInterstitial_pressed"]
103 |
104 | [connection signal="pressed" from="CanvasLayer/BtnRewardedVideo" to="." method="_on_BtnRewardedVideo_pressed"]
105 |
106 |
107 |
--------------------------------------------------------------------------------
/examples/godot-3/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kloder-games/godot-admob/f5996ed22dfab457d611bc1f4f32d6305de3dcd2/examples/godot-3/icon.png
--------------------------------------------------------------------------------
/examples/godot-3/main.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 | var admob = null
4 | var instance_id = get_instance_id() # The instance id from Godot
5 |
6 | var is_init_with_content_rating = true #Init AdMob with additional Content Rating parameters (Android and iOS)
7 |
8 | var is_for_child_directed_treatment = false # If true, maxAdContetRating will be ignored (your maxAdContentRating would can not be other than "G")
9 | var is_personalized = true # Ads are personalized by default, GDPR compliance within the European Economic Area may require you to disable personalization.
10 | var max_ad_content_rating = "G" #It's value must be "G", "PG", "T" or "MA".
11 | #If the rating of your app in Play Console and your config of maxAdContentRating in AdMob are not matched, your app can be banned by Google.
12 |
13 |
14 | var is_real = false # Show real ad or test ad
15 | var is_top = true # Show the banner on top or bottom
16 |
17 | const AD_BANNER_ID = {
18 | "Android": "ca-app-pub-3940256099942544/6300978111",
19 | "iOS" : "ca-app-pub-3940256099942544/2934735716"
20 | }
21 | #[Replace with your Ad Unit ID and delete this message]
22 |
23 | const AD_INTERSTITIAL_ID = {
24 | "Android": "ca-app-pub-3940256099942544/1033173712",
25 | "iOS" : "ca-app-pub-3940256099942544/4411468910"
26 | }
27 | #[Replace with your Ad Unit ID and delete this message]
28 |
29 | const AD_REWARDED_ID = {
30 | "Android": "ca-app-pub-3940256099942544/5224354917",
31 | "iOS" : "ca-app-pub-3940256099942544/1712485313"
32 | }
33 | #[Replace with your Ad Unit ID and delete this message]
34 |
35 | var platform_os = OS.get_name()
36 |
37 | func _ready():
38 | if(Engine.has_singleton("AdMob")):
39 | admob = Engine.get_singleton("AdMob")
40 | if is_init_with_content_rating:
41 | admob.initWithContentRating(is_real, instance_id, is_for_child_directed_treatment, is_personalized, max_ad_content_rating)
42 | else:
43 | admob.init(is_real, instance_id)
44 | print("OS: " + platform_os)
45 | loadBanner()
46 | loadInterstitial()
47 | loadRewardedVideo()
48 |
49 | print_debug(get_tree().connect("screen_resized", self, "_on_screen_resized"))
50 |
51 | # Loaders
52 | func loadBanner():
53 | if admob != null:
54 | admob.loadBanner(AD_BANNER_ID[platform_os], is_top)
55 |
56 | func loadInterstitial():
57 | if admob != null:
58 | admob.loadInterstitial(AD_INTERSTITIAL_ID[platform_os])
59 |
60 | func loadRewardedVideo():
61 | if admob != null:
62 | admob.loadRewardedVideo(AD_REWARDED_ID[platform_os])
63 |
64 | # Events
65 | func _on_BtnBanner_toggled(pressed):
66 | if admob != null:
67 | if pressed: admob.showBanner()
68 | else: admob.hideBanner()
69 |
70 | func _on_BtnInterstitial_pressed():
71 | if admob != null:
72 | admob.showInterstitial()
73 |
74 | func _on_BtnRewardedVideo_pressed():
75 | if admob != null:
76 | admob.showRewardedVideo()
77 |
78 | func _on_admob_network_error():
79 | print("Network Error")
80 |
81 | func _on_admob_ad_loaded():
82 | print("Ad loaded success")
83 | if admob != null:
84 | prints("BannerWidth: " + str(admob.getBannerWidth()), "BannerHeight: " + str(admob.getBannerHeight()))
85 | get_node("CanvasLayer/BtnBanner").set_disabled(false)
86 |
87 | func _on_interstitial_not_loaded():
88 | print("Error: Interstitial not loaded")
89 |
90 | func _on_interstitial_loaded():
91 | print("Interstitial loaded")
92 | get_node("CanvasLayer/BtnInterstitial").set_disabled(false)
93 |
94 | func _on_interstitial_close():
95 | print("Interstitial closed")
96 | get_node("CanvasLayer/BtnInterstitial").set_disabled(true)
97 | loadInterstitial()
98 |
99 | func _on_rewarded_video_ad_loaded():
100 | print("Rewarded loaded success")
101 | get_node("CanvasLayer/BtnRewardedVideo").set_disabled(false)
102 |
103 | func _on_rewarded_video_ad_closed():
104 | print("Rewarded closed")
105 | get_node("CanvasLayer/BtnRewardedVideo").set_disabled(true)
106 | loadRewardedVideo()
107 |
108 | func _on_rewarded(currency, amount):
109 | print("Reward: " + currency + ", " + str(amount))
110 | get_node("CanvasLayer/LblRewarded").set_text("Reward: " + currency + ", " + str(amount))
111 |
112 |
113 | # Resize the banner
114 | func _on_screen_resized():
115 | if admob != null:
116 | admob.resize() # this function makes the banner load and show again, but with different size
117 |
--------------------------------------------------------------------------------
/examples/godot-3/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://main.gd" type="Script" id=1]
4 |
5 | [node name="Node2D" type="Node2D" index="0"]
6 |
7 | script = ExtResource( 1 )
8 | __meta__ = {
9 | "__editor_plugin_screen__": "3D"
10 | }
11 |
12 | [node name="CanvasLayer" type="CanvasLayer" parent="." index="0"]
13 |
14 | layer = 1
15 | offset = Vector2( 0, 0 )
16 | rotation = 0.0
17 | scale = Vector2( 1, 1 )
18 | transform = Transform2D( 1, 0, 0, 1, 0, 0 )
19 |
20 | [node name="BtnBanner" type="Button" parent="CanvasLayer" index="0"]
21 |
22 | anchor_left = 0.0
23 | anchor_top = 0.0
24 | anchor_right = 0.0
25 | anchor_bottom = 0.0
26 | margin_left = 437.0
27 | margin_top = 220.0
28 | margin_right = 587.0
29 | margin_bottom = 295.0
30 | rect_pivot_offset = Vector2( 0, 0 )
31 | rect_clip_content = false
32 | focus_mode = 2
33 | mouse_filter = 0
34 | mouse_default_cursor_shape = 0
35 | size_flags_horizontal = 1
36 | size_flags_vertical = 1
37 | disabled = true
38 | toggle_mode = true
39 | enabled_focus_mode = 2
40 | shortcut = null
41 | group = null
42 | text = "Show/Hide Banner"
43 | flat = false
44 | align = 1
45 | _sections_unfolded = [ "Rect" ]
46 |
47 | [node name="BtnInterstitial" type="Button" parent="CanvasLayer" index="1"]
48 |
49 | anchor_left = 0.0
50 | anchor_top = 0.0
51 | anchor_right = 0.0
52 | anchor_bottom = 0.0
53 | margin_left = 437.0
54 | margin_top = 305.0
55 | margin_right = 587.0
56 | margin_bottom = 380.0
57 | rect_pivot_offset = Vector2( 0, 0 )
58 | rect_clip_content = false
59 | focus_mode = 2
60 | mouse_filter = 0
61 | mouse_default_cursor_shape = 0
62 | size_flags_horizontal = 1
63 | size_flags_vertical = 1
64 | disabled = true
65 | toggle_mode = false
66 | enabled_focus_mode = 2
67 | shortcut = null
68 | group = null
69 | text = "Show Interstitial"
70 | flat = false
71 | align = 1
72 | _sections_unfolded = [ "Rect" ]
73 |
74 | [node name="BtnRewardedVideo" type="Button" parent="CanvasLayer" index="2"]
75 |
76 | anchor_left = 0.0
77 | anchor_top = 0.0
78 | anchor_right = 0.0
79 | anchor_bottom = 0.0
80 | margin_left = 437.0
81 | margin_top = 394.0
82 | margin_right = 588.0
83 | margin_bottom = 469.0
84 | rect_pivot_offset = Vector2( 0, 0 )
85 | rect_clip_content = false
86 | focus_mode = 2
87 | mouse_filter = 0
88 | mouse_default_cursor_shape = 0
89 | size_flags_horizontal = 1
90 | size_flags_vertical = 1
91 | disabled = true
92 | toggle_mode = false
93 | enabled_focus_mode = 2
94 | shortcut = null
95 | group = null
96 | text = "Show Rewarded Video"
97 | flat = false
98 | align = 1
99 | _sections_unfolded = [ "Rect" ]
100 |
101 | [node name="LblRewarded" type="Label" parent="CanvasLayer" index="3"]
102 |
103 | anchor_left = 0.0
104 | anchor_top = 0.0
105 | anchor_right = 0.0
106 | anchor_bottom = 0.0
107 | margin_right = 1026.0
108 | margin_bottom = 32.0
109 | rect_pivot_offset = Vector2( 0, 0 )
110 | rect_clip_content = false
111 | mouse_filter = 2
112 | mouse_default_cursor_shape = 0
113 | size_flags_horizontal = 1
114 | size_flags_vertical = 4
115 | text = "REWARDED VIDEO RETURN"
116 | align = 1
117 | valign = 1
118 | percent_visible = 1.0
119 | lines_skipped = 0
120 | max_lines_visible = -1
121 | _sections_unfolded = [ "Rect" ]
122 |
123 | [connection signal="toggled" from="CanvasLayer/BtnBanner" to="." method="_on_BtnBanner_toggled"]
124 |
125 | [connection signal="pressed" from="CanvasLayer/BtnInterstitial" to="." method="_on_BtnInterstitial_pressed"]
126 |
127 | [connection signal="pressed" from="CanvasLayer/BtnRewardedVideo" to="." method="_on_BtnRewardedVideo_pressed"]
128 |
129 |
130 |
--------------------------------------------------------------------------------
/examples/godot-3/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=3
10 |
11 | [android]
12 |
13 | modules="org/godotengine/godot/GodotAdMob"
14 |
15 | [application]
16 |
17 | config/name="testAdmob"
18 | run/main_scene="res://main.tscn"
19 | config/icon="res://icon.png"
20 |
21 | [display]
22 |
23 | window/handheld/orientation="sensor"
24 | window/stretch/mode="viewport"
25 | window/stretch/aspect="keep_height"
26 |
--------------------------------------------------------------------------------
/issue_template.md:
--------------------------------------------------------------------------------
1 | **OS target (Android/iOS):**
2 |
3 |
4 | **Godot version:**
5 |
6 |
7 | **Issue description:**
8 |
9 |
10 |
--------------------------------------------------------------------------------
/templates/README.md:
--------------------------------------------------------------------------------
1 | # Templates generated with Godot Engine 2.1 and Admob Module (Not Firebase)
2 |
3 | This templates are compiled using Godot 2.1 (Stable) and this module (Admob).
4 |
5 | For the compilation I change the minSDKVersion to 9 for reach more devices.
6 |
7 | For use this templates you can use the [Godot Documentation](http://docs.godotengine.org/en/stable/reference/compiling_for_android.html#installing-the-templates) for use the custom templates.
8 |
9 | :)
10 |
--------------------------------------------------------------------------------
/templates/android_debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kloder-games/godot-admob/f5996ed22dfab457d611bc1f4f32d6305de3dcd2/templates/android_debug.apk
--------------------------------------------------------------------------------
/templates/android_release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kloder-games/godot-admob/f5996ed22dfab457d611bc1f4f32d6305de3dcd2/templates/android_release.apk
--------------------------------------------------------------------------------