I am trying to understand from here - https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html how we can trigger a js function from Unity.
I have followed that and edited my html file such as:
var myGameInstance = null;
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
myGameInstance = unityInstance;
loadingBar.style.display = "none";
}).catch((message) => {
alert(message);
});
};
function CheckAlert() {
alert("MessageReceived");
}
and my C# code is as:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
public class Bridge : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void SendMessage(string message);
#endif
void Start () {
Invoke("SendToJS", 2.0f);
}
public void SendToJS () {
Debug.Log ("Sending message to JavaScript");
#if UNITY_WEBGL && !UNITY_EDITOR
SendMessage ("Ok");
#endif
}
}
and my js.jslib library is as follows:
mergeInto(LibraryManager.library, {
SendMessage: function (message) {
CheckAlert();
},
});
But unfortunately nothing gets sent through, I never receive an alert message which I should.
How do I fix this?
Related
I have been trying to make my game, play an ad every 5 rounds/losses. I have tried copying some scripts, but they don't work for me. I am a really early developer and don't know much about c# and unity. If you find a solution tell me in which script I need to put the code.
My GameManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public GameObject gameOverCanvas;
public AdsManager ads;
private void Start()
{
Time.timeScale = 1;
ads.ShowBanner();
}
public void GameOver()
{
gameOverCanvas.SetActive(true);
Time.timeScale = 0;
ads.PlayAd();
}
public void Replay()
{
SceneManager.LoadScene(0);
}
}
My AdsManager script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsManager : MonoBehaviour, IUnityAdsListener
{
#if UNITY_IOS
string gameId = "#######";
#else
string gameId = "#######";
#endif
Action onRewardedAdSuccess;
// Start is called before the first frame update
void Start()
{
Advertisement.Initialize(gameId);
Advertisement.AddListener(this);
ShowBanner();
}
public void PlayAd()
{
if(Advertisement.IsReady("Interstitial_Android"))
Advertisement.Show("Interstitial_Android");
}
public void PlayRewardedAd(Action onSuccess)
{
onRewardedAdSuccess = onSuccess;
if(Advertisement.IsReady("Rewarded_Android"))
{
Advertisement.Show("Rewarded_Android");
}
else
{
Debug.Log("Rewarded ad is not ready!");
}
}
public void ShowBanner()
{
if (Advertisement.IsReady("Banner_Android"))
{
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
Advertisement.Banner.Show("Banner_Android");
}
else
{
StartCoroutine(RepeatShowBanner());
}
}
public void HideBanner()
{
Advertisement.Banner.Hide();
}
IEnumerator RepeatShowBanner()
{
yield return new WaitForSeconds(1);
ShowBanner();
}
public void OnUnityAdsReady(string placementId)
{
Debug.Log("ADS ARE READY!");
}
public void OnUnityAdsDidError(string message)
{
Debug.Log("ERROR: " + message);
}
public void OnUnityAdsDidStart(string placementId)
{
Debug.Log("VIDEO STARTED!");
}
public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
{
if (placementId == "Rewarded_Android" && showResult == ShowResult.Finished)
{
onRewardedAdSuccess.Invoke();
}
}
}
If you need any more scripts then tell me. I would appreciate any feedback.
Create a counter, increment it after every game and then check if you reached required number of games.
You would need to create counter and required games variables. Then, put the increment and if statement code in your GameOver method:
public void GameOver()
{
gameOverCanvas.SetActive(true);
Time.timeScale = 0;
gameCount++; //increment game count
if(gameCount >= gamesToShowAd) // check if player played enough games to show ad
{
ads.PlayAd();
gameCount = 0; // reset counter
}
}
If you wish, you could consider saving game count using https://docs.unity3d.com/ScriptReference/PlayerPrefs.html or using ready online solution, but it's up to you.
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 just started using Unity, to make a small game called flappy duck.
I wanne have an online leaderboard so everyone can beat each others highscore.
I stumbled on this error Assets\scripts\PlayerController.cs(65,9): error CS0103: The name 'playfabManager' does not exist in the current context
I cand cant find anything wrong. BTW i am using a tutorial
from CoCo Code https://www.youtube.com/watch?v=e2RXDso6fWU&t=266s he uses playfab i am trying to
get this working in my own game.
THIS IS THE SCRIPT THAT MAKES THE TEXT DISPLAY THE HIGHSCORE
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HighSScore : MonoBehaviour
{
public Text HighScore;
// Start is called before the first frame update
void Start()
{
HighScore.text = PlayerPrefs.GetInt("highscore").ToString();
}
}
THIS IS THE PLAYFAB MANAGER
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;
public class PlayFabManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Login();
}
void Login()
{
var request = new LoginWithCustomIDRequest
{
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true
};
PlayFabClientAPI.LoginWithCustomID(request, OnSuccess, OnError);
}
void OnSuccess(LoginResult result)
{
Debug.Log("Successful login/account create!");
}
void OnError(PlayFabError error)
{
Debug.Log("Error while logging in/creating account!");
Debug.Log(error.GenerateErrorReport());
}
public void SendLeaderboard(int score)
{
var request = new UpdatePlayerStatisticsRequest
{
Statistics = new List<StatisticUpdate>
{
new StatisticUpdate
{
StatisticName = "score",
Value = score
}
}
};
PlayFabClientAPI.UpdatePlayerStatistics(request, OnLeaderboardUpdate, OnError);
}
void OnLeaderboardUpdate(UpdatePlayerStatisticsResult result)
{
Debug.Log("succsessfull send leaderboard");
}
}`
LAST IS THIS THE PLAYERCONTROLLER
were the error is based on line 65
I am trying to send the highscore to the leaderboard in playfab.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
[SerializeField] TextMeshProUGUI scoreText;
Rigidbody2D bird;
int score = 0;
bool dead = false;
int highscore = 0;
// Start is called before the first frame update
void Start()
{
bird = transform.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
public void update ()
{
if (Input.GetKeyDown("space") && !dead)
{
bird.velocity = new Vector2(0, 6f);
}
if (Input.GetKeyDown("r"))
{
SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);
}
if (score > highscore)
{
highscore = score;
SendLeaderboard();
PlayerPrefs.SetInt("highscore", score);
}
}
void OnCollisionEnter2D()
{
dead = true;
score = 0;
scoreText.text = "0";
}
void OnTriggerExit2D(Collider2D col)
{
if (col.gameObject.tag == "PointTrigger")
{
score++;
scoreText.text = score.ToString();
}
}
void OnTriggerExit(Collider col)
{
if (col.gameObject.tag == "PointTrigger")
{
score++;
scoreText.text = score.ToString();
}
}
public void SendLeaderboard()
{
playfabManager.SendLeaderboard(highscore);
}
}
I hope someone can help me.
Most probably in PlayerController you wanted to have a
[SerializeField] private PlayFabManager playfabManager;
and either reference it via the Inspector or at runtime via e.g.
private void Awake ()
{
// Try and get the component if it is attached to the same object as this
if(! playfabManager) playfabManager = GetComponent<PlayFabManager>();
// Or try and find it anywhere in the scene
if(! playfabManager) playfabManager = FindObjectOfType<PlayFabManager>();
// Or simply create and attach it to the same object as this one
if(! playfabManager) playfabManager = gameObject.AddComponent<PlayFabManager>();
}
Or - and in my eyes this would be the more correct solution - the PlayerFabManager should not be a MonoBehaviour at all but rather simply do
public class PlayFabManager
{
public void Login()
{
...
}
...
}
And in PlayerController you'd rather do
private readonly PlayFabManager playfabManager = new PlayFabManager();
private void Start ()
{
playfabManager.Login();
}
I have a script in my new clicker game that uses InvokeRepeating:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AutomineController : MonoBehaviour {
static int WoodMiners = 0;
static int StoneMiners = 0;
public Text already_mining;
public Text invalid_transaction;
public Text too_many_miners;
// Error message code
private IEnumerator TooManyMinersCore ()
{
already_mining.gameObject.SetActive (false);
invalid_transaction.gameObject.SetActive (false);
too_many_miners.gameObject.SetActive (true);
yield return new WaitForSeconds (1.5f);
too_many_miners.gameObject.SetActive (false);
}
// The code that does the actual mining
private static void WoodMiner ()
{
Debug.Log("Here");
ChopWood.Add ();
}
// The code that "hires" the miners
public void HireWoodMiner ()
{
if (WoodMiners < 5) {
WoodMiners += 1;
InvokeRepeating("WoodMiner", 0.1f, 3.0f);
} else {
StartCoroutine(TooManyMinersCore());
}
}
}
For some reason, the InvokeRepeating() doesn't work- it should run the WoodMiner() method when the HireWoodMiner() method is run. Why is this?
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.