我有一个Unity游戏应用程序,我想更新我的应用程序,在发布以玩商店(更新)后,我发现广告不再起作用。尽管该应用程序可以很好地与测试广告完美配合,但是当将测试广告单元ID(和测试应用程序ID)与我的广告单元ID和应用程序ID切换时,该应用程序将无法正常工作。
我确实确保等待几天,以允许Google / AdMob系统找出更改并开始展示广告,但是没有结果,这根本不起作用。
我认为(GoogleMobileAdsDemoScript.cs文件)中的所有代码都正确无误,因为它几乎没有任何变化。
但是,就AndroidManifest文件而言,我不确定,因为我不知道它的外观或工作方式。我确实尝试过多次更改(如一些指南/问答这样,并对这个主题有建议),但是那样会使我的项目无法构建,并且会弹出其他错误,或者根本就不会。修复项目。 我提供给您的内容现在可以100%正常运行(有测试广告ID的情况下),但仍然有效,但是在有我的广告ID时不会显示任何广告。
注意:这是一个Unity项目Android游戏,
在这里我用******
来覆盖我的ID,在真实文件中有正确的ID
Assets/Plugins/Android/
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.unity3d.player" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" /> <!-- MM: added this to skip permissions in start, Success! this works -->
</activity>
<activity android:name="com.facebook.unity.FBUnityLoginActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityDialogsActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityAppLinkActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityDeepLinkingActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
<activity android:name="com.facebook.unity.AppInviteDialogActivity" />
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb23423*******" />
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider23423******" android:exported="true" />
</application>
</manifest>
这部分直接取自GoogleMobileAdsDemoScript.CS,(我做了一些细微调整),因此必须完全没问题。如果没有,则不应显示测试广告。
using System;
using UnityEngine;
using GoogleMobileAds.Api;
// Example script showing how to invoke the Google Mobile Ads Unity plugin.
public class GoogleMobileAdsDemoScript : MonoBehaviour
{
private BannerView bannerView;
public InterstitialAd interstitial;
private RewardBasedVideoAd rewardBasedVideo;
private float deltaTime = 0.0f;
private static string outputMessage = string.Empty;
public static string OutputMessage
{
set { outputMessage = value; }
}
public void Start()
{
#if UNITY_ANDROID
string appId = "ca-app-pub-******";
#elif UNITY_IPHONE
string appId = "ca-app-pub-*******";
#else
string appId = "unexpected_platform";
#endif
MobileAds.SetiOSAppPauseOnBackground(true);
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
// Get singleton reward based video ad reference.
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
// RewardBasedVideoAd is a singleton, so handlers should only be registered once.
this.rewardBasedVideo.OnAdLoaded += this.HandleRewardBasedVideoLoaded;
this.rewardBasedVideo.OnAdFailedToLoad += this.HandleRewardBasedVideoFailedToLoad;
this.rewardBasedVideo.OnAdOpening += this.HandleRewardBasedVideoOpened;
this.rewardBasedVideo.OnAdStarted += this.HandleRewardBasedVideoStarted;
this.rewardBasedVideo.OnAdRewarded += this.HandleRewardBasedVideoRewarded;
this.rewardBasedVideo.OnAdClosed += this.HandleRewardBasedVideoClosed;
this.rewardBasedVideo.OnAdLeavingApplication += this.HandleRewardBasedVideoLeftApplication;
}
public void Update()
{
// Calculate simple moving average for time to render screen. 0.1 factor used as smoothing
// value.
this.deltaTime += (Time.deltaTime - this.deltaTime) * 0.1f;
}
// MM: this is the UI we don't need from tutorial
/*
public void OnGUI()
{
GUIStyle style = new GUIStyle();
Rect rect = new Rect(0, 0, Screen.width, Screen.height);
style.alignment = TextAnchor.LowerRight;
style.fontSize = (int)(Screen.height * 0.06);
style.normal.textColor = new Color(0.0f, 0.0f, 0.5f, 1.0f);
float fps = 1.0f / this.deltaTime;
string text = string.Format("{0:0.} fps", fps);
GUI.Label(rect, text, style);
// Puts some basic buttons onto the screen.
GUI.skin.button.fontSize = (int)(0.035f * Screen.width);
float buttonWidth = 0.35f * Screen.width;
float buttonHeight = 0.15f * Screen.height;
float columnOnePosition = 0.1f * Screen.width;
float columnTwoPosition = 0.55f * Screen.width;
Rect requestBannerRect = new Rect(
columnOnePosition,
0.05f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(requestBannerRect, "Request\nBanner"))
{
this.RequestBanner();
}
Rect destroyBannerRect = new Rect(
columnOnePosition,
0.225f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(destroyBannerRect, "Destroy\nBanner"))
{
this.bannerView.Destroy();
}
Rect requestInterstitialRect = new Rect(
columnOnePosition,
0.4f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(requestInterstitialRect, "Request\nInterstitial"))
{
this.RequestInterstitial();
}
Rect showInterstitialRect = new Rect(
columnOnePosition,
0.575f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(showInterstitialRect, "Show\nInterstitial"))
{
this.ShowInterstitial();
}
Rect destroyInterstitialRect = new Rect(
columnOnePosition,
0.75f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(destroyInterstitialRect, "Destroy\nInterstitial"))
{
this.interstitial.Destroy();
}
Rect requestRewardedRect = new Rect(
columnTwoPosition,
0.05f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(requestRewardedRect, "Request\nRewarded Video"))
{
this.RequestRewardBasedVideo();
}
Rect showRewardedRect = new Rect(
columnTwoPosition,
0.225f * Screen.height,
buttonWidth,
buttonHeight);
if (GUI.Button(showRewardedRect, "Show\nRewarded Video"))
{
this.ShowRewardBasedVideo();
}
Rect textOutputRect = new Rect(
columnTwoPosition,
0.925f * Screen.height,
buttonWidth,
0.05f * Screen.height);
GUI.Label(textOutputRect, outputMessage);
}
*/
//MM: end of UI, can hide it again later.
// Returns an ad request with custom ad targeting.
private AdRequest CreateAdRequest()
{
return new AdRequest.Builder()
//.AddTestDevice(AdRequest.TestDeviceSimulator)
//.AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
//MM: these filters are not required
/*
//.AddKeyword("game")
//.SetGender(Gender.Male)
//.SetBirthday(new DateTime(1985, 1, 1))
//.TagForChildDirectedTreatment(false)
//.AddExtra("color_bg", "9B30FF")
*/
.Build();
}
public void RequestBanner() //MM: this funciton was made from "private" to "public" so it can be accessed from within other scripts
{
// These ad units are configured to always serve test ads.
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID
string adUnitId = "ca-app-pub-*******";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-*******";
#else
string adUnitId = "unexpected_platform";
#endif
// Clean up banner ad before creating a new one.
if (this.bannerView != null)
{
this.bannerView.Destroy();
}
// Create a 320x50 banner at the top of the screen.
this.bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Bottom);
// Register for ad events.
this.bannerView.OnAdLoaded += this.HandleAdLoaded;
this.bannerView.OnAdFailedToLoad += this.HandleAdFailedToLoad;
this.bannerView.OnAdOpening += this.HandleAdOpened;
this.bannerView.OnAdClosed += this.HandleAdClosed;
this.bannerView.OnAdLeavingApplication += this.HandleAdLeftApplication;
// Load a banner ad.
this.bannerView.LoadAd(this.CreateAdRequest());
}
public void RequestInterstitial() //MM: changed this from "private" to "public" so it be accessible from other places as well
{
// These ad units are configured to always serve test ads.
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID
string adUnitId = "ca-app-pub-********";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-*********";
#else
string adUnitId = "unexpected_platform";
#endif
// Clean up interstitial ad before creating a new one.
if (this.interstitial != null)
{
this.interstitial.Destroy();
}
// Create an interstitial.
this.interstitial = new InterstitialAd(adUnitId);
// Register for ad events.
this.interstitial.OnAdLoaded += this.HandleInterstitialLoaded;
this.interstitial.OnAdFailedToLoad += this.HandleInterstitialFailedToLoad;
this.interstitial.OnAdOpening += this.HandleInterstitialOpened;
this.interstitial.OnAdClosed += this.HandleInterstitialClosed;
this.interstitial.OnAdLeavingApplication += this.HandleInterstitialLeftApplication;
// Load an interstitial ad.
this.interstitial.LoadAd(this.CreateAdRequest());
}
private void RequestRewardBasedVideo()
{
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID string adUnitId = "ca-app-pub-***********";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-*********";
#else
string adUnitId = "unexpected_platform";
#endif
this.rewardBasedVideo.LoadAd(this.CreateAdRequest(), adUnitId);
}
public void ShowInterstitial()
{
if (this.interstitial.IsLoaded())
{
this.interstitial.Show();
}
else
{
MonoBehaviour.print("Interstitial is not ready yet");
}
}
private void ShowRewardBasedVideo()
{
if (this.rewardBasedVideo.IsLoaded())
{
this.rewardBasedVideo.Show();
}
else
{
MonoBehaviour.print("Reward based video ad is not ready yet");
}
}
#region Banner callback handlers
public void HandleAdLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLoaded event received");
}
public void HandleAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
MonoBehaviour.print("HandleFailedToReceiveAd event received with message: " + args.Message);
}
public void HandleAdOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdOpened event received");
}
public void HandleAdClosed(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdClosed event received");
}
public void HandleAdLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLeftApplication event received");
}
#endregion
#region Interstitial callback handlers
public void HandleInterstitialLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleInterstitialLoaded event received");
}
public void HandleInterstitialFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
MonoBehaviour.print(
"HandleInterstitialFailedToLoad event received with message: " + args.Message);
}
public void HandleInterstitialOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleInterstitialOpened event received");
}
public void HandleInterstitialClosed(object sender, EventArgs args)
{
MonoBehaviour.print("HandleInterstitialClosed event received");
}
public void HandleInterstitialLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleInterstitialLeftApplication event received");
}
#endregion
#region RewardBasedVideo callback handlers
public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoLoaded event received");
}
public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
MonoBehaviour.print(
"HandleRewardBasedVideoFailedToLoad event received with message: " + args.Message);
}
public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoOpened event received");
}
public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoStarted event received");
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoClosed event received");
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
string type = args.Type;
double amount = args.Amount;
MonoBehaviour.print(
"HandleRewardBasedVideoRewarded event received for " + amount.ToString() + " " + type);
}
public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoLeftApplication event received");
}
#endregion
}
最后,这是我在游戏控制器中请求广告的地方。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Facebook.Unity;
public class GameControll : MonoBehaviour {
public GoogleMobileAdsDemoScript GoogAdsTemp; //MM: this is a referance to the GoogleMobileAdsDemoScript for ads/example
public static int coin;
public static bool pause;
public Text coine, distance;
public Text goCoin, goScore, goBScore, lamlCount;
public GameObject MainMenuPanel, GameOverPanel, powerPanel, SaveLifePanel;
private AudioListener al;
private int lcoin, lCount;
private float timerl = 0;
private bool lifesave = false;
public GameObject saveButton;
private Image sl;
public static bool SaveMe = false, loadS;
public static bool showAd = false;
private bool changeScorecolor;
private float cc = 0;
public static bool GoogleMobileAdsStarted = true; //MM: this is just a testing bool, I created, that's it.
void Start()
{
GoogAdsTemp.Start (); //MM: this is to initiate GoogleMobileAdsDemoScript // sort of to link with ad engine.
coin = 0;
changeScorecolor = false;
distance.color = new Color(1, 1, 1, 1);
pause = false;
showAd = false;
GoogleMobileAdsStarted = true; //MM: added this
al = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<AudioListener>();
al.enabled = true;
if (ProtectedPrefs.HasKey("Coins"))
{
lcoin = ProtectedPrefs.GetInt("Coins");
}
else {
lcoin = 0;
}
GetLamp();
sl = saveButton.GetComponent<Image>();
//MM: created bellow from here
if (GoogleMobileAdsStarted == true)
{
Debug.Log ("We are loading ads now, serving from start method");
GoogAdsTemp.RequestBanner (); //MM: this is to show banner ads
Debug.Log ("1st ad from start just served");
GoogAdsTemp.RequestBanner (); //MM: this is to show banner ads
Debug.Log ("2nd ad from start just served");
GoogAdsTemp.RequestInterstitial(); //MM: added this, interstitial after gameover (to load it)
Debug.Log ("We just requested for an Interstitial load, from Start");
}
//MM: created up to here
}
void Update()
{
//MM: created bellow from here
if (GoogleMobileAdsStarted == false)
{
Debug.Log ("We are turning GoogleMobileAdsStarted to = true now and serving an ad");
GoogleMobileAdsStarted = true;
this.GoogAdsTemp.RequestBanner(); //MM: this is to show banner ads
Debug.Log ("Ads just served in from Update method.");
}
//MM: this is to check whether or not interstitial is loaded, if not, then it loads it again.
if (GoogAdsTemp.interstitial == null)
{
GoogAdsTemp.RequestInterstitial (); //MM: added this, interstitial after gameover (to load it)
Debug.Log ("We just requested for another Interstitial load, now from update");
}
//MM: created up to here
if (lifesave == true && Controller.iDie && !loadS && !SaveMe)
{
showAd = false;
SaveLifePanel.SetActive(true);
timerl += Time.deltaTime;
sl.fillAmount -= Time.deltaTime / 1.8F;
if (timerl >= 1.8F)
{
timerl = 0;
sl.fillAmount = 1;
SaveLifePanel.SetActive(false);
Invoke("GameOver", 0.5f);
loadS = true;
}
}
if (itemAbsorb.getLamp) GetLamp();
coine.text = coin.ToString();
distance.text = Controller.Distance.ToString("00000000") + "0";
if (Controller.Distance > 10 && Controller.Distance > ProtectedPrefs.GetFloat("HighScore") && !changeScorecolor) {
cc += Time.deltaTime;
if (cc < 1)
{
distance.color = new Color(1, 0, 0, 1);
}
else if (cc > 1 && cc < 1.5f)
{
distance.color = new Color(1, 1, 1, 1);
}
else if (cc > 1.5f && cc < 2)
{
distance.color = new Color(1, 0, 0, 1);
}
else if (cc > 2 && cc < 2.5f)
{
distance.color = new Color(1, 1, 1, 1);
}
else if(cc>2.5f){
distance.color = new Color(1f, 0.92f, 0.016f, 1f);
cc = 0;
changeScorecolor = true;
}
}
if (Controller.iDie && ProtectedPrefs.GetInt("mLamp") < 1)
{
MainMenuPanel.SetActive(false);
Invoke("GameOver", 0.5f);
}
else if (Controller.iDie && ProtectedPrefs.GetInt("mLamp") > 0 && !lifesave)
{
MainMenuPanel.SetActive(false);
lifesave = true;
loadS = false;
}
}
public void SaveLife()
{
SaveLifePanel.SetActive(false);
ProtectedPrefs.SetInt("mLamp", lCount - 1);
Controller.iDie = false;
SaveMe = true;
lifesave = false;
GetLamp();
MainMenuPanel.SetActive(true);
timerl = 0;
sl.fillAmount = 1;
}
public void GetLamp()
{
if (ProtectedPrefs.HasKey("mLamp"))
{
lCount = ProtectedPrefs.GetInt("mLamp");
}
else {
lCount = 0;
}
itemAbsorb.getLamp = false;
lamlCount.text = lCount.ToString();
}
private void GameOver()
{
showAd = true;
GoogAdsTemp.ShowInterstitial(); //MN: added this, interstitial after gameover (to show it)
Debug.Log ("We just served it, hopefully");
GameOverPanel.SetActive(true);
powerPanel.SetActive(false);
ProtectedPrefs.SetInt("Coins", lcoin + coin);
goCoin.text = "Coins: " + coin.ToString();
goScore.text = "Score: " + Controller.Distance.ToString("f0") + "0";
if (Controller.Distance > ProtectedPrefs.GetFloat("HighScore"))
{
ProtectedPrefs.SetFloat("HighScore", Controller.Distance);
}
if (ProtectedPrefs.HasKey("HighScore"))
{
goBScore.text = "Best Score: " + ProtectedPrefs.GetFloat("HighScore").ToString("f0") + "0";
}
else
{
goBScore.text = "Best Score: " + Controller.Distance.ToString("f0") + "0";
}
if (FB.IsLoggedIn)
{
#if !UNITY_EDITOR
StartCoroutine (Facebook.Unity.FBManager.SetScore ());
#endif
}
}
public void isPause() {
pause = true;
al.enabled = false;
}
public void isContinue()
{
pause = false;
al.enabled = true;
}
public void isRestart()
{
SceneManager.LoadScene("main");
}
public void isMainMenu()
{
pause = false;
SceneManager.LoadScene("menu");
}
}
非常感谢您的帮助!
答案 0 :(得分:0)
我很惊讶您能够像这样上传应用程序。清单中的 package 字段应与您应用的软件包名称(com.mycompany.myawesomegame)相匹配。您应该能够在Unity的播放器设置中更新程序包名称。 Admob还需要知道正确的软件包名称。
编辑:我实际上可能是一个疯子。该值可能会被覆盖。您是否尝试过从另一台设备上的商店下载该应用程序?