I made a simple 2d game with not many objects and it runs fine on my Xperia ST. But when i integrated admobs to show both banner and interstitial ads on game over screen the gameplay lags and gets slow.
My code for admob and how they are used is given below
Player Script
using UnityEngine;
using System.Collections;
public class PlayerMotion : MonoBehaviour {
public GameObject gameOverTag,spawner,camera,adObject;
SpawnScript spawnScript;
GoogleMobileAdsDemoScript adScript;
// Use this for initialization
void Awake() {
adObject=GameObject.Find("Ads");// ads is a game object which was kept from main menu screen
}
void Start () {
spawnScript= spawner.GetComponent<SpawnScript> ();
//adScript=camera.GetComponent<GoogleMobileAdsDemoScript> ();//GoogleMobileAdsDemoScript is the ad script
adScript=adObject.GetComponent<GoogleMobileAdsDemoScript> ();
adScript.hideBanner ();
adScript.requestInterstitial ();
}
// Update is called once per frame
void Update () {
//some more code
}
}
public void Movement()
{
//some code
}
void OnCollisionEnter2D(Collision2D other){
//some code
}
void OnGUI(){
if (gameOver) {
if((adScript.timesInterstitalRequested)%5==0)
adScript.ShowInterstitial ();
else
adScript.showBanner ();
//some more code
}
}
}
Here is GoogleMobileAdsDemoScript Code
using System;
using UnityEngine;
using GoogleMobileAds;
using GoogleMobileAds.Api;
// Example script showing how to invoke the Google Mobile Ads Unity plugin.
public class GoogleMobileAdsDemoScript : MonoBehaviour
{
private BannerView bannerView;
private InterstitialAd interstitial;
public int timesBannerRequested=0,timesInterstitalRequested=0;
void Awake() {
DontDestroyOnLoad (this);
}
void Start()
{
}
public void requestBanner(){
//Requesting BannerView
timesBannerRequested = timesBannerRequested + 1;
#if UNITY_EDITOR
string adUnitId = "ca-app-pub-asdas";
#elif UNITY_ANDROID
string adUnitId = "ca-app-pub-asd";
#elif UNITY_IPHONE
string adUnitId = "INSERT_IOS_BANNER_AD_UNIT_ID_HERE";
#else
string adUnitId = "unexpected_platform";
#endif
bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Bottom);
AdRequest requestBanner = new AdRequest.Builder().Build();
bannerView.LoadAd(requestBanner);
//bannerView.Hide ();
}
public void requestInterstitial(){
timesInterstitalRequested = timesInterstitalRequested + 1;
//Requesting Interstitial
#if UNITY_EDITOR
string adUnitIdInterstitial = "ca-app-pub-dfada";
#elif UNITY_ANDROID
string adUnitIdInterstitial = "ca-app-pub-asdas";
#elif UNITY_IPHONE
string adUnitIdInterstitial = "INSERT_IOS_INTERSTITIAL_AD_UNIT_ID_HERE";
#else
string adUnitIdInterstitial = "unexpected_platform";
#endif
interstitial = new InterstitialAd(adUnitIdInterstitial);
AdRequest requestInterstitial = new AdRequest.Builder().Build();
interstitial.LoadAd(requestInterstitial);
}
public void showBanner()
{
bannerView.Show ();
}
public void destroyBanner()
{
bannerView.Destroy ();
}
public void hideBanner()
{
bannerView.Hide ();
}
public void ShowInterstitial()
{
if (interstitial.IsLoaded())
{
interstitial.Show();
}
else
{
print("Interstitial is not ready yet.");
}
}
}
Your logic seems solid from a first glance,
I would however optimize the OnGUI function. since this is the most vital function of all,
when considering the mobile hardware.
void OnGUI(){
if (gameOver) {
if(adScript.bannerShowing == false) {
if((adScript.timesInterstitalRequested)%5==0)
adScript.ShowInterstitial ();
else
adScript.showBanner ();
}
}
}
Then add a bannerShowing boolean on the GoogleMobileAdsDemoScript code and make it true when visible
and false when the banner is hidden,
its a bad idea to call ShowInterstital or showBanner multiple times in OnGUI since it all runs on a single thread.
Google Admob uses some very big 8MB DLL if you integrate that into Unity project.
Common feedback is: the App starts slower and the app loads scenes with Admob slow for the fist time.
You may try to implement native Android plugin into your Unity app. Basically that plugin would be written in Java and it would work fast.
Related
I'm facing issue in my AdsController.cs script
Everything is working fine in my game but the ads are not showing in the app
please solve this issue and also tell me where I'm wrong i think i did something wrong with my AdsController script thats why the warnings is Assets\Scripts\AdmobManager.cs(21,16): warning CS0219: The variable 'AppId' is assigned but its value is never used
either remove the variables or use them I want to use the variables, that's why the ads are not showing because the ad ids are stored in a variable but not used it means the AdMob manager doesn't know the ad ids values. Can you know how can I use these variables in my script? I think there is a problem while implementing in my script
Here is my 'AdsController.cs' Script
using UnityEngine;
public class _AdsController : MonoBehaviour
{
public GameManager gameManager_1;
public GameManager_2 gameManager_2;
public GameManager_3 gameManager_3;
public AdManager adManager;
public AdmobManager admobManager;
[Header("Ads Manager")]
public UnityadsManager unityadsManager;
bool showAds = true;
void Start()
{
if (adManager.AdNetwork == AdManager.adNetwork.Admob)
{
unityadsManager.gameObject.SetActive(false);
}
if (adManager.AdNetwork == AdManager.adNetwork.UnityAds)
{
admobManager.gameObject.SetActive(false);
}
}
void Update()
{
if (gameManager_1 != null)
{
if (gameManager_1.Succes || gameManager_1.Failed)
{
Show();
}
}
if (gameManager_2 != null)
{
if (gameManager_2.Succes || gameManager_2.Failed)
{
Show();
}
}
if (gameManager_3 != null)
{
if (gameManager_3.Succes || gameManager_3.Failed)
{
Show();
}
}
}
public void Show()
{
if (showAds)
{
if (adManager.AdNetwork == AdManager.adNetwork.Admob)
{
admobManager.ShowInterstitial();
showAds = false;
}
if (adManager.AdNetwork == AdManager.adNetwork.UnityAds)
{
unityadsManager.ShowInterstitial();
showAds = false;
}
}
}
}
Here is my 'AdmobManager.cs' Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AdmobManager : MonoBehaviour
{
public AdManager adManager;
[HideInInspector]
public bool AdmobeRewardFinished = false;
private BannerView bannerView;
private InterstitialAd interstitial;
private RewardedAd rewardedAd;
private void Awake()
{
#if UNITY_ANDROID
string AppId = "ca-app-pub-5990016123172046~4832056793";
#elif UNITY_IPHONE
string AppId = "ca-app-pub-3940256099942544~1458002511";
#else
string AppId = "unexpected_platform";
#endif
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(initStatus => { });
AdmobeRewardFinished = false;
}
void Start()
{
if (PlayerPrefs.GetInt("ads") != 1)
{
RequestBanner();
RequestInterstitial();
}
}
public void RequestBanner()
{
#if UNITY_ANDROID
string BannerId = "ca-app-pub-5990016123172046/8196586737";
#elif UNITY_IPHONE
string BannerId = "ca-app-pub-3940256099942544/2934735716";
#else
string BannerId = "unexpected_platform";
#endif
// Create a 320x50 banner at the top of the screen.
this.bannerView = new BannerView(adManager.BannerId, AdSize.SmartBanner, AdPosition.Bottom);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the banner with the request.
this.bannerView.LoadAd(request);
}
private void RequestInterstitial()
{
#if UNITY_ANDROID
string InterstitialId = "ca-app-pub-5990016123172046/8005015043";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-3940256099942544/4411468910";
#else
string adUnitId = "unexpected_platform";
#endif
// Initialize an InterstitialAd.
this.interstitial = new InterstitialAd(adManager.interstitialId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.interstitial.LoadAd(request);
}
public void ShowInterstitial()
{
if (this.interstitial.IsLoaded() && PlayerPrefs.GetInt("ads") != 1)
{
this.interstitial.Show();
}
}
}
I made a simple game, and for the test I decided to add an advertisement there. Until the moment of importing the package with ads, everything was compiled fine, but after that the compiler started giving errors. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Advertisements;
public class DrwLog : MonoBehaviour
{
public GameObject pnel;
public GameObject[] ColorButtons;
public GameObject button;
// Start is called before the first frame update
void Start()
{
if (Advertisement.isSupported)
{
Advertisement.Initialize("*******", false );
}
Invoke("Bn", 10f);
pnel.active = false;
}
// Update is called once per frame
void Update()
{
}
public void Clicked(bool on)
{
if (on)
{
button.GetComponent<AudioSource>().Play();
}
else
{
button.GetComponent<AudioSource>().Stop();
}
}
public void ColorChnge(int clr)
{
button.GetComponent<Image>().color = ColorButtons[clr].GetComponent<Image>().color;
}
public void PnelEnble()
{
if (!pnel.active)
{
pnel.active = true;
}
else
{
pnel.active = false;
}
}
public void Bn()
{
if (Advertisement.IsReady())
{
Advertisement.Show("bn");
}
}
}
Unity Monetization - full Add-On name.
Now I am doing a project for my final term in university and my area changed the scene by gazing(google VR SDK).
At first, I just put a code to change the scene. It worked. But I want some enhance, so I used gaze timer which I watched at youtube (link: https://www.youtube.com/watch?v=bmMaVTV8UqY)
Now, the gaze Timer animation is working but the SceneSwitcher function in NexScene1 code isn't working.
I've done 'build' after adding the new scene that I add gaze timer function.
Also, I used tagged which shown in the youtube.
That's all I did.
public class VRGaze : MonoBehaviour {
public Image imgGaze;
public float totalTime = 2;
bool gvrStatus;
float gvrTimer;
public int distanceOfRay = 10;
private RaycastHit _hit;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (gvrStatus)
{
gvrTimer += Time.deltaTime;
imgGaze.fillAmount = gvrTimer / totalTime;
}
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0.5f));
if(Physics.Raycast(ray, out _hit, distanceOfRay))
{
if(imgGaze.fillAmount == 1 && _hit.transform.CompareTag("NexScene1"))
{
_hit.transform.gameObject.GetComponent<NexScene1>().SceneSwitcher();
}
}
}
public void GVROn() {
gvrStatus = true;
}
public void GVROff() {
gvrStatus = false;
gvrTimer = 0;
imgGaze.fillAmount = 0;
}
}
public class NexScene1 : MonoBehaviour {
public UnityEngine.UI.Scrollbar obj_scroll_;
public GameObject player;
public void PointEnter()
{
StartCoroutine(TimeToAction());
}
public void PointExit()
{
StopAllCoroutines();
}
public void SceneSwitcher()
{
SceneManager.LoadScene("Page2");
}
void Start () {
}
// Update is called once per frame
void Update () {
}
}
Not an actual error but just the SwitchScene function is not called at VRGaze
Not an error but the console says:
It is recommended to use GvrPointerPhysicsRaycaster or
GvrPointerGrahpicRaycaster with GvrPointerInputModule.
I've followed Google Admob step by step tutorial on implementing Interstitial Ad on my 3D Unity game, but the interstitial didn't shown when running the game on my device.
Do you know what's wrong in my code, and how to fix it?
Ad Script:
private InterstitialAd interstitial;
static int loadCount = 0;
bool GameHasEnded = false;
float RestartDelay = 1.5f;
private void Start()
{
#if UNITY_ANDROID
string appId = "ca-app-pub-3940256099942544/1033173712";
#else
string appId = "unexpected_platform";
#endif
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
this.RequestInterstitial();
if ((loadCount % 3) == 0) // only show ad every third time
{
if (this.interstitial.IsLoaded())
{
this.interstitial.Show();
}
}
}
void Restart()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().path);
loadCount = loadCount + 1;
}
private void RequestInterstitial()
{
#if UNITY_ANDROID
string adUnitId = "ca-app-pub-3940256099942544/1033173712";
#else
string adUnitId = "unexpected_platform";
#endif
// Initialize an InterstitialAd.
this.interstitial = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.interstitial.LoadAd(request);
}
For me the problem seems to happen because the interstitial ad takes a while to load (sometimes up to 3 seconds). You're trying to call it too fast, and it's not loaded, so nothing happens. What I did was continually try to show the interstitial ad in void Update until it shows (using a bool called shown):
void Update () {
if (shown == false) {
ShowInterstitial();
}
}
public void ShowInterstitial()
{
if (interstitial.IsLoaded())
{
interstitial.Show();
shown = true;
} else {
Debug.Log ("Interstitial is not ready yet.");
}
}
You could also load the ad at the beginning of the level, and then only call it when the round is over.
You're trying to initalize admob and request new interstitial on every restart. You have to create one instance of AdmobController or whatever and use it.
public class AdManager{
public static AdManager instance;
private void Awake(){
if(instance == null) {
instance = this;
DontDestroyOnLoad(gameObject);
} else {
Destroy(gameObject);
return;
}
}
private void Start()
{
#if UNITY_ANDROID
string appId = "ca-app-pub-3940256099942544/1033173712";
#else
string appId = "unexpected_platform";
#endif
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
this.RequestInterstitial();
}
public void showInterstitial(){
if ((loadCount % 3) == 0) // only show ad every third time
{
if (this.interstitial.IsLoaded())
{
this.interstitial.Show();
}
}
}
then when you want to show interstitial
AdController.instance.showInterstitial();
It may have syntax error or something but you've get the idea.
This is how I currently have my Sound Manager setup for a small RPG and I was just wondering if this was good practice.
What I was trying to go for was to have my two methods (PlayBGMusic and PlaySound) to be "public static" so I would not have to grab the GameObject by tag and the Script in almost all of my other scripts that want to play a sound. If I do make them "public static" then I would have to make my variables the same which takes away from placing anything in the inspector.
public class Sound_Manager : MonoBehaviour {
// Allow the user to decide if music should be on or off.
public bool backgroundMusicOn;
// Allow the user to decide if sound should be on or off.
public bool soundOn;
// The music volume.
[Range(0,1)]
public float musicVolume;
// The sound volume.
[Range(0,1)]
public float soundVolume;
// The Background music to be used for any manipulations.
private AudioSource _bgMusic;
// Play a background song.
public void PlayBGMusic(AudioSource music){
...
}
// Mute Current Background Song.
public void MuteUnMuteBGMusic(){
....
}
// Play a sound.
public void PlaySound(AudioClip sfx, Vector3 location){
...
}
}
Is this a proper way of handling something like this or is there another way that could be more simple?
I think you can't play BGmusic and sound in one GameObject,because every audio must play whith single audion source,this is my code of AudioManager.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class AudioManager : MonoBehaviour
{
public AudioClip[] audioSources;
public GameObject audioPrefabSource;
public Dictionary<string,AudioClip> audioClips;
static GameObject audioPrefab;
static GameObject instance;
static AudioSource musicPlayer;
public static AudioManager audioManager;
Dictionary<string,Audio> aliveSounds;
AudioListener al;
void Awake ()
{
audioManager = this;
al = GetComponent<AudioListener> ();
audioClips = new Dictionary<string, AudioClip> ();
foreach (AudioClip a in audioSources) {
audioClips.Add (a.name, a);
}
instance = this.gameObject;
audioPrefab = audioPrefabSource;
musicPlayer = audio;
aliveSounds = new Dictionary<string, Audio> ();
//DontDestroyOnLoad(gameObject);
}
void Update ()
{
if (!GameSetting.hasMusic) {
musicPlayer.Pause ();
} else {
if (!musicPlayer.isPlaying) {
musicPlayer.Play ();
}
}
if (!GameSetting.hasSound && aliveSounds.Count > 0) {
foreach (Audio a in aliveSounds.Values) {
a.StopSound ();
}
aliveSounds.Clear ();
}
if (!al.enabled) {
al.enabled = true;
}
}
public static void PlaySoundOnce (string name)
{
if (!GameSetting.hasSound) {
return;
}
if (!audioManager.audioClips.ContainsKey (name)) {
return;
}
GameObject go = GameObject.Instantiate (audioPrefab) as GameObject;
go.transform.parent = instance.transform;
Audio a = go.GetComponent<Audio> ();
a.PlaySoundOnce (audioManager.audioClips [name]);
}
public static void PlayMusic (string name)
{
if (!GameSetting.hasMusic) {
return;
}
if (musicPlayer.clip == null || musicPlayer.clip.name != name) {
// musicPlayer.clip = audioManager.audioClips [name];
musicPlayer.clip = Resources.Load ("Audio/" + name, typeof(AudioClip)) as AudioClip;
musicPlayer.Stop ();
musicPlayer.loop = true;
musicPlayer.Play ();
} else {
musicPlayer.loop = true;
musicPlayer.Play ();
}
}
}
There is another class for Audio,it must be made to a audioprefab.
using UnityEngine;
using System.Collections;
public class Audio : MonoBehaviour
{
public void PlaySoundOnce (AudioClip audioClip)
{
StartCoroutine (PlaySoundCoroutine (audioClip));
}
IEnumerator PlaySoundCoroutine (AudioClip audioClip)
{
audio.PlayOneShot (audioClip);
yield return new WaitForSeconds (audioClip.length);
Destroy (gameObject);
}
public void PlaySoundLoop (AudioClip audioClip)
{
audio.clip = audioClip;
audio.loop = true;
audio.Play ();
}
public void StopSound ()
{
audio.Stop ();
Destroy (gameObject);
}
}
Like this,and I ignored audio's position,I used 2D sound.
I recommend turning the sound manager into a singleton class. In that way you can have all the properties in the inspector and use the singleton object to globally access all your properties, even destroying the gameobject completely when not needed .