Godot 4.5 ile AdMob Reklam Entegrasyonu: Kesin ve Çalışan Rehber

Godot 4.5 ile AdMob Reklam Entegrasyonu: Kesin ve Çalışan Rehber

06.03.2026
101

Godot motorunda oyun geliştiriyorsanız ve oyununuzdan gelir elde etmek istiyorsanız, AdMob entegrasyonu en popüler ve etkili yöntemlerden biridir. Ancak, doğru eklentiyi seçmek, yapılandırmak ve özellikle "Ödüllü Reklamlar" (Rewarded Ads) gibi karmaşık sistemleri sorunsuz çalıştırmak zorlayıcı olabilir.

Bu makalede, Godot 4.5 versiyonu ve güncel AdMob eklentilerini kullanarak sıfır hatalı, stabil bir reklam entegrasyonunun nasıl yapılacağını adım adım inceleyeceğiz. Sık karşılaşılan hatalara ve çözüm yollarına da değineceğiz.


1. Hazırlık ve Eklenti Kurulumu

Godot 4.x için resmi ve en stabil AdMob eklentisi genellikle Poing Studios (veya benzeri güvenilir geliştiriciler) tarafından sağlanan eklentilerdir.


Eklenti Kurulum Adımları:

  1. İlgili AdMob eklentisini indirin ve projenizin addons/ klasörüne dahil edin.
  2. Godot'un Project -> Project Settings -> Plugins sekmesinden eklentiyi aktifleştirin.
  3. Eklenti aktifleştirildiğinde, genellikle alt panelde veya proje ayarlarında bir "AdMob" bölümü oluşur. Yada Proje menüsüne eklenir; Proje -> Araçlar -> AdMob Manager


En Önemli Adım (AdMob App ID): AdMob panelinden (veya test için Google'ın sağladığı) App ID'nizi almanız gerekir. Bu ID genellikle ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY formatındadır. Bu ID'yi eklentinin ayarlarına veya Android export ayarlarındaki ilgili meta-data bölümüne (AndroidManifest.xml içine gömülecek şekilde) mutlaka girmelisiniz. Godot 4.5 ve Poing.Studios’a ait AdMob eklentisi için App ID’nin girileceği dosya Addons -> AdMob -> Android -> setup.gd dosyasıdır.


2. Doğru Kod Mimarisi (Güvenli Yükleme ve Gösterme)

Reklamları yönetirken, oyununuzun çökmesini önlemek için "Güvenli Yükleme" ve "Callback (Geri Çağırma)" mantığını doğru kurmak çok önemlidir.

İşte Game Manager betiğinizde kullanmanız gereken kesin yapı:


A. Değişkenleri Tanımlama

Test aşamasında mutlaka Google'ın sağladığı test ID'lerini kullanın. Gerçek ID'ler ile test yaparsanız AdMob hesabınız banlanabilir!

# --- ADMOB TEST ID'LERİ ---

const BANNER_ID = "ca-app-pub-3940256099942544/6300978111"

const INTERSTITIAL_ID = "ca-app-pub-3940256099942544/1033173712"

const REWARDED_ID = "ca-app-pub-3940256099942544/5224354917"


# --- REKLAM DEĞİŞKENLERİ ---

var _ad_view = null

var _interstitial_ad = null

var _rewarded_ad = null

var _reward_earned: bool = false

var _waiting_for_reward: bool = false


var _inter_loader = null

var _inter_cb = null

var _fs_inter_cb = null

var _rew_loader = null

var _rew_cb = null

var _fs_rew_cb = null

var _current_rew_listener = null


B. AdMob'u Başlatma (Initialization)

AdMob SDK'sını oyun başlarken bir kez başlatmanız gerekir. Bu işlem genellikle işletim sistemi kontrolü ile yapılır (Sadece Android/iOS'te çalışması için).

func _setup_admob() -> void:

               # Windows/macOS/Linux'ta reklam yüklemeye çalışma, çökmeyi önle

               if OS.get_name() in ["Windows", "macOS", "Linux"]: return

               

               var mobile_ads: Variant = MobileAds

               if mobile_ads and mobile_ads.has_method("initialize"):

                              if not Engine.has_meta("admob_initialized"):

                                              mobile_ads.initialize()

                                              Engine.set_meta("admob_initialized", true)

                                              

               # Banner reklamı hemen yükle ve göster

               await get_tree().create_timer(0.2).timeout

               var req_class: Variant = AdRequest

               if not req_class: return

               var ad_request = req_class.new()

               var ad_view_class: Variant = AdView

               var ad_size_class: Variant = AdSize

               var ad_pos_class: Variant = AdPosition

               if ad_view_class:

                              _ad_view = ad_view_class.new(BANNER_ID, ad_size_class.BANNER, ad_pos_class.Values.BOTTOM)

                              if _ad_view:

                                              _ad_view.load_ad(ad_request)

                                              _ad_view.show()


C. Ödüllü Reklam (Rewarded Ad) Yükleme ve Gösterme Mantığı

Ödüllü reklamlar en karmaşık olanlardır çünkü kullanıcının reklamı sonuna kadar izleyip izlemediğini (Ödül kazanıp kazanmadığını) güvenli bir şekilde takip etmeniz gerekir.

func _load_and_show_rewarded(btn_ad: Button, reason: String) -> void:

               btn_ad.text = "Reklam Yükleniyor..."

               btn_ad.disabled = true

               

               # PC'de test ediyorsan direkt ödülü ver

               if OS.get_name() in ["Windows", "macOS", "Linux"]:

                              _give_reward_safely()

                              return

                              

               var rew_loader_class: Variant = RewardedAdLoader

               var rew_cb_class: Variant = RewardedAdLoadCallback

               

               if rew_loader_class and rew_cb_class:

                              _rew_loader = rew_loader_class.new()

                              _rew_cb = rew_cb_class.new()

                              var w_self = weakref(self)

                              

                              var on_r_loaded = func(ad):

                                              var s = w_self.get_ref()

                                              if s:

                                                              s._rewarded_ad = ad

                                                              if is_instance_valid(btn_ad): btn_ad.text = "Reklam Gösteriliyor..."

                                                              

                                                              # Kapatılma (Dismiss) Callback'i

                                                              var fs_class: Variant = FullScreenContentCallback

                                                              if fs_class:

                                                                              s._fs_rew_cb = fs_class.new()

                                                                              var w_s2 = weakref(s)

                                                                              var on_dismiss = func():

                                                                                             var s2 = w_s2.get_ref()

                                                                                             if s2:

                                                                                                             # Reklam kapandığında, eğer ödül kazanılmışsa ödülü ver

                                                                                                             if s2._reward_earned or s2._waiting_for_reward:

                                                                                                                             s2._give_reward_safely()

                                                                                                             else:

                                                                                                                             # Kullanıcı reklamı yarıda kapattı

                                                                                                                             if is_instance_valid(btn_ad):

                                                                                                                                             btn_ad.text = "🎥 REKLAM İZLE"

                                                                                                                                             btn_ad.disabled = false

                                                                              

                                                                              if s._fs_rew_cb.has_method("set_on_ad_dismissed_full_screen_content"):

                                                                                             s._fs_rew_cb.set_on_ad_dismissed_full_screen_content(on_dismiss)

                                                                              else:

                                                                                             s._fs_rew_cb.on_ad_dismissed_full_screen_content = on_dismiss

                                                                              ad.full_screen_content_callback = s._fs_rew_cb

                                                              

                                                              # Ödül Kazanılma (Earned Reward) Callback'i

                                                              var listener_class: Variant = OnUserEarnedRewardListener

                                                              if listener_class:

                                                                              s._current_rew_listener = listener_class.new()

                                                                              var on_earned = func(item):

                                                                                             var s3 = w_self.get_ref()

                                                                                             if s3: s3._reward_earned = true # Sadece bayrağı işaretle

                                                                                             

                                                                              if s._current_rew_listener.has_method("set_on_user_earned_reward"):

                                                                                             s._current_rew_listener.set_on_user_earned_reward(on_earned)

                                                                              else:

                                                                                             s._current_rew_listener.on_user_earned_reward = on_earned

                                                                              

                                                                              ad.show(s._current_rew_listener)

                                                              else:

                                                                              ad.show()

                                              else:

                                                              if ad and ad.has_method("destroy"): ad.destroy()

                                                              

                              var on_r_failed = func(err):

                                              var s = w_self.get_ref()

                                              if s and is_instance_valid(btn_ad):

                                                              btn_ad.text = "Yüklenemedi! Tekrar Dene"

                                                              btn_ad.disabled = false

                                                              

                              # Callback'leri bağla ve yüklemeyi başlat

                              if _rew_cb.has_method("set_on_ad_loaded"):

                                              _rew_cb.set_on_ad_loaded(on_r_loaded)

                                              _rew_cb.set_on_ad_failed_to_load(on_r_failed)

                              else:

                                              _rew_cb.on_ad_loaded = on_r_loaded

                                              _rew_cb.on_ad_failed_to_load = on_r_failed

                                              

                              var req_class: Variant = AdRequest

                              if req_class: _rew_loader.load(REWARDED_ID, req_class.new(), _rew_cb)


D. Ödülü Güvenlice Verme

Ödül verme işlemini doğrudan on_user_earned_reward içinde yapmak bazen Godot'un thread (iş parçacığı) sisteminde çökmelere neden olabilir. Bu yüzden o fonksiyon sadece _reward_earned = true yapar, ödülü ise reklam kapandıktan sonra tetiklenen on_ad_dismissed içinden çağırdığımız _give_reward_safely() fonksiyonunda veririz.

func _give_reward_safely() -> void:

               _reward_earned = false

               _waiting_for_reward = false

               

               # Ödülü ver (Örn: +10 Elmas)

               _saved_diamonds += 10

               save_progress()

               

               show_info_popup("TEBRİKLER!", "+10 Elmas kazandınız! 💎")

               update_ui()


E. Hafıza Yönetimi (Memory Leaks Önleme)

Sahne değişirken veya oyun kapanırken reklam objelerini hafızadan temizlemek çok önemlidir, aksi takdirde uygulamanız zamanla yavaşlayabilir veya çökebilir.

func _exit_tree() -> void:

               if _ad_view != null:

                              if _ad_view.has_method("destroy"): _ad_view.destroy()

                              _ad_view = null

               if _interstitial_ad != null:

                              if _interstitial_ad.has_method("destroy"): _interstitial_ad.destroy()

                              _interstitial_ad = null

               if _rewarded_ad != null:

                              if _rewarded_ad.has_method("destroy"): _rewarded_ad.destroy()

                              _rewarded_ad = null


               _inter_loader = null

               _inter_cb = null

               _fs_inter_cb = null

               _rew_loader = null

               _rew_cb = null

               _fs_rew_cb = null

               _current_rew_listener = null


3. Karşılaşılan Tuzaklar ve Çözümler

Tuzak 1: Hatalı Class Referansları Yüzünden Çökme

Belirti: Reklam butonuna basıldığında oyun donuyor veya kapanıyor. Neden: Eklentinin sağladığı sınıfları (Örn: RewardedAdLoader) doğrudan RewardedAdLoader.new() olarak çağırıyorsunuz. Eğer eklenti doğru yüklenmediyse, Godot bu sınıfı bulamaz ve çöker. Çözüm: Yukarıdaki mimaride kullandığımız gibi, sınıfları önce Variant olarak kontrol edip (var rew_loader_class: Variant = RewardedAdLoader), var olup olmadıklarını teyit ettikten sonra kullanın. Bu sayede eklenti yoksa bile oyun çökmez, sadece reklam çalışmaz.


Tuzak 2: PC'de Test Ederken Oyunun Çökmesi

Belirti: Godot editöründen oyunu başlattığınızda siyah ekran geliyor veya hata veriyor. Neden: AdMob sadece Android ve iOS ortamlarında çalışır. PC'de Java köprüsü olmadığı için SDK başlatılamaz. Çözüm: AdMob fonksiyonlarının en başına daima OS kontrolü ekleyin: if OS.get_name() in ["Windows", "macOS", "Linux"]: return


Tuzak 3: Zayıf Referans (Weakref) Kullanılmaması

Belirti: Reklam izlenirken sahne değiştirildiğinde veya obje silindiğinde Null Instance hatası alınıyor. Neden: Callback fonksiyonları (Lambda fonksiyonları) içinde doğrudan self (yani bulunduğunuz sahne) kullanırsanız, reklam izlenirken o sahne silinirse kod silinmiş bir objeye ulaşmaya çalışır. Çözüm: Mimarimizde gösterildiği gibi, weakref(self) kullanarak sahnenin hala var olup olmadığını kontrol edin (var s = w_self.get_ref(); if s:).


Tuzak 4: Gerçek Reklam ID'leri ile Test Yapmak

Belirti: Birkaç gün sonra AdMob hesabınız sınırlandırılır veya kapatılır. Neden: Geliştirme aşamasında kendi uygulamanızdaki gerçek reklamlara tıklamanız, AdMob'un geçersiz trafik politikalarını ihlal eder. Çözüm: Uygulamanız Google Play Store'a yüklenip onaylanana kadar DAİMA Google'ın sağladığı genel test reklam ID'lerini kullanın.


Son Söz

AdMob entegrasyonu, asenkron işlemler (callback'ler) ve platforma özgü sınırlamalar nedeniyle dikkat gerektirir. Yukarıdaki mimari, olası çökmeleri önlemek için "defansif programlama" (defensive programming) teknikleriyle hazırlanmıştır ve Godot 4.x projelerinde güvenle kullanılabilir.


Yorumlar

İlk yorumu siz yazın.

Yorum Yaz