Unity使用Android原生接入Admob

447 阅读4分钟

前言:Unity接入Admob的方式,有详细的官方文档https://developers.google.com/admob/unity/quick-start?hl=zh-cn这个对接应该没啥问题,但是如果要用Android原生的方式对接在Unity项目中对接需要怎么做呢。具体逻辑也就是在Unity中触发Android的方法,然后在Android中通知Unity。应该有很多会选择把Unity项目导出Android项目,然后在Android Studio里面开发。这么做的话,如果Unity中有什么改动,都需要每次导出,这样非常的不友好。我们把对接Admob打包为一个Android依赖库,这样我们改动也互不影响。接下来看我们需要怎么做吧。

创建一个Android项目,新建一个AdMobPlugin的AndroidLibrary

新建一个AdMobManager管理广告

package com.unitygame.admobplugin;
import android.app.Activity;
import android.util.Log;

import androidx.annotation.NonNull;

import com.applovin.impl.sdk.o.DDMob;
import com.applovin.impl.sdk.o.ad.FullScreenAdCallback;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
import com.google.android.gms.ads.MobileAds;
import com.unity3d.player.UnityPlayer;

import java.lang.reflect.Method;

public class AdMobManager {
    private static final String TAG = "AdMobManager";
    private Activity mActivity;
    private RewardedAd mRewardedAd;
    private String unityGameObjectName;
    private String AD_UNIT_ID = "ca-app-pub-3940256099942544/5224354917";

    public AdMobManager(Activity activity, String unityGameObjectName) {
        this.mActivity = activity;
        this.unityGameObjectName = unityGameObjectName;
        new Thread(
                () -> {
                    // Initialize the Google Mobile Ads SDK on a background thread.
                    MobileAds.initialize(activity, initializationStatus -> {});
                })
                .start();
        DDMob.init(activity, "61a33b2a0661d0b46a6a8a7b690588d7");
    }

    public void loadRewardedAd() {
        if (mRewardedAd != null) {
            mRewardedAd = null;
        }
        mActivity.runOnUiThread(() -> {
            // Load AdMob Rewarded Ad here
            RewardedAd.load(mActivity, AD_UNIT_ID, new AdRequest.Builder().build(), new RewardedAdLoadCallback() {
                @Override
                public void onAdLoaded(RewardedAd ad) {
                    mRewardedAd = ad;
                    Log.d(TAG, "Ad loaded.");
                }

                @Override
                public void onAdFailedToLoad(LoadAdError adError) {
                    Log.d(TAG, "Failed to load ad: " + adError.getMessage());
                    mRewardedAd = null;
                }
            });
        });
    }

    public void showRewardedAd() {
        if (mRewardedAd != null) {
            mRewardedAd.setFullScreenContentCallback(new FullScreenAdCallback(mRewardedAd) {
                @Override
                public void onShowed() {
                    // Called when ad is shown.
                    Log.d(TAG, "FullScreenAdCallback onShowed");
                }

                @Override
                public void onImpression() {
                    // Called when an impression is recorded for an ad.
                    Log.d(TAG, "FullScreenAdCallback onImpression");
                }

                @Override
                public void onFailedToShow(@NonNull AdError error) {
                    // Called when ad fails to show.
                    Log.d(TAG, "FullScreenAdCallback onFailedToShow");
                    loadRewardedAd();
                }

                @Override
                public void onDismissed() {
                    // Called when ad is dismissed.
                    Log.d(TAG, "FullScreenAdCallback onDismissed");
                    loadRewardedAd();
                }

                @Override
                public void onClicked() {
                    // Called when a click is recorded for an ad.
                    Log.d(TAG, "FullScreenAdCallback onClicked");
                }
            });

            mActivity.runOnUiThread(() -> {
                mRewardedAd.show(mActivity, new OnUserEarnedRewardListener() {
                    @Override
                    public void onUserEarnedReward(@NonNull RewardItem reward) {
                        // Notify Unity of the reward
                        UnityPlayer.UnitySendMessage(unityGameObjectName, "OnUserEarnedReward", reward.getType() + "," + reward.getAmount());
                    /*try {
                        // 获取 UnityPlayer 类
                        Class<?> unityPlayerClass = Class.forName("com.unity3d.player.UnityPlayer");
                        // 获取 currentActivity 静态字段
                        Object currentActivity = unityPlayerClass.getField("currentActivity").get(null);
                        // 获取 UnitySendMessage 静态方法
                        Method unitySendMessageMethod = unityPlayerClass.getMethod("UnitySendMessage", String.class, String.class, String.class);
                        // 构造传递给 Unity 的消息
                        String message = reward.getType() + "," + reward.getAmount();
                        // 调用 UnitySendMessage 方法
                        unitySendMessageMethod.invoke(null, unityGameObjectName, "OnUserEarnedReward", message);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }*/
                    }
                });
            });
        } else {
            Log.d(TAG, "The rewarded ad wasn't loaded yet.");
            loadRewardedAd();
        }
    }
}

DDMob是我们一个运营统计的库,这个可以直接删除。setFullScreenContentCallback这个监听用Admob的即可

配置build.gradle

implementation 'com.google.android.gms:play-services-ads:23.3.0'
implementation 'com.example.mylibrary:unitycls:1.0.0'

implementation 'com.example.mylibrary:unitycls:1.0.0'这个是我本地的maven库,里面包含了unity-classes.jar 为了防止UnityPlayer找不到而无法打包aar,如何直接加到项目当中,因为Unity项目构建的时候就包含了这个jar,为了防止类冲突,所以放在了本地Maven,这样打包的时候不会把jar打包进去,可以Unity项目导出Android项目在项目里面找到这个unity-classes.jar,放在你的本地Maven中,本地Maven的方式可以看我之前的文章里面有教程,也可以使用我注释的反射的方式来调用。

最终我们打包了AdMobPlugin.aar。将AdMobPlugin.aar放在本地Maven当中,因为在Unity构建的时候,aar文件是无法直接打包构建的。

Unity中调用

将打包的AdMobPlugin.aar在Unity的launcherTemplate中引用。

    implementation 'com.google.android.gms:play-services-ads:23.3.0'
    implementation 'com.example.mylibrary:admobplugin:1.0.0'

注意这里需要加上implementation 'com.google.android.gms:play-services-ads:23.3.0'的引用,因为我们打包的aar里面,远程依赖库是无法打包在aar库里面的。

LauncherManifest中加上你的APPLICATION_ID

    <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-2853159195783569~8887651234"/>

在你的启动场景中加上一个AdManager空对象,新建AdManager脚本挂载到这个空对象中。

using UnityEngine;
using System;
public class AdManager : MonoBehaviour
{
    public static AdManager Instance { get; private set; }

    private AndroidJavaObject adMobManager;

    public event Action OnCustomEvent;

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);

            using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
                adMobManager = new AndroidJavaObject("com.unitygame.admobplugin.AdMobManager", activity, gameObject.name);
            }
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void ShowRewardedAd()
    {
        Debug.Log("Unity显示广告");
        adMobManager.Call("showRewardedAd");
    }

    public void LoadRewardedAd(){
        Debug.Log("Unity加载广告");
        adMobManager.Call("loadRewardedAd");
    }

    // This method will be called from the Android plugin
    public void OnUserEarnedReward(string rewardTypeAndAmount)
    {
        // Split the rewardTypeAndAmount to get type and amount
        var parts = rewardTypeAndAmount.Split(',');
        var rewardType = parts[0];
        var rewardAmount = int.Parse(parts[1]);

        Debug.Log($"User earned reward: Type = {rewardType}, Amount = {rewardAmount}");
        OnCustomEvent?.Invoke();
        // Handle the reward here (e.g., update player's balance)
    }
}

最后在你的场景中去监听广告播放完毕的回调和触发广告的播放,并处理相关的逻辑,以下是我的示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class AdManagerHome : MonoBehaviour
{

    public Text goldtext;

    void Start()
    {
        LoadRewardedAd();
        // 注册当前场景的回调函数
        if (AdManager.Instance != null)
        {
            AdManager.Instance.OnCustomEvent += HandleEvent;
        }
    }

    // 回调函数,处理当前场景的逻辑
    private void HandleEvent()
    {
        Debug.Log("我是收到的回调");
        // 在这里编写该场景特有的逻辑
    }

    public void LoadRewardedAd()
    {
        AdManager.Instance.LoadRewardedAd();
    }

    public void ShowRewardedAd()
    {
        AdManager.Instance.ShowRewardedAd();
    }


    private void OnDestroy() {
                // 当场景切换时,取消注册回调
      if (AdManager.Instance != null)
     {
         AdManager.Instance.OnCustomEvent -= HandleEvent;
      }
    }

}

以上就是完整的Android的Abmob在Unity项目中的使用了,希望可以给你们带来帮助。