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.
Related
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 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.
This is my code. I think it is this script.
I have no idea where the error is, but I think it is in OnTriggerEnter2d in the second if statement.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pickup : MonoBehaviour
{
private InventoryTest inventory;
public GameObject itembutton;
// Start is called before the first frame update
void Start()
{
inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<InventoryTest>();
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.CompareTag("Player")) {
for (int i = 0; i < inventory.slots.Length; i++) {
if (inventory.isfull[i] == false) {
inventory.isfull[i] = true;
Instantiate(itembutton, inventory.slots[i].transform, false);
Destroy(gameObject);
break;
}
}
}
}
// Update is called once per frame
void Update()
{
}
}
For testing I have two conversations at index 0 and 1.
And I want it to play the first conversation index 0 and then when it finish playing it to start playing the next conversation at index 1.
This is the script with the playing methods. The first should play a list/array of conversations one by one the second should play only a single conversation :
PlayConversations and PlayConversation.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class ConversationTrigger : MonoBehaviour
{
public List<Conversation> conversations = new List<Conversation>();
public static List<int> conversationsToPlay = new List<int>();
public bool conversationEnd;
public GameObject canvas;
public static int conversationIndex;
private DialogueManager dialoguemanager;
private string jsonPath;
public void InitJsonPath()
{
jsonPath = Application.persistentDataPath + "/" + "Json.txt";
}
private void Start()
{
conversationIndex = 0;
dialoguemanager = FindObjectOfType<DialogueManager>();
}
public IEnumerator PlayConversations()
{
canvas.SetActive(true);
conversationEnd = false;
var conversations = conversationsToPlay.ToArray(); // Copy the list
conversationsToPlay.Clear(); // Immediately clear the original list
for (int i = 0; i < conversations.Length; i++) // iterate over the array
{
// Now you also don't need to remove items anymore,
// since you already cleared the list
yield return StartCoroutine(PlayConversation(conversations[i]));
}
}
public IEnumerator PlayConversation(int index)
{
if (conversations.Count > 0 &&
conversations[index].Dialogues.Count > 0)
{
for (int i = 0; i < conversations[index].Dialogues.Count; i++)
{
if (dialoguemanager != null)
{
dialoguemanager.StartDialogue(conversations[index].Dialogues[i]);
}
while (DialogueManager.dialogueEnded == false)
{
yield return null;
}
}
conversationEnd = true;
conversationIndex = index;
canvas.SetActive(false);
Debug.Log("Conversation Ended");
}
}
public void SaveConversations()
{
string jsonTransform = JsonHelper.ToJson(conversations.ToArray(), true);
File.WriteAllText(jsonPath, jsonTransform);
}
public void LoadConversations()
{
string jsonTransform = File.ReadAllText(jsonPath);
conversations.Clear();
conversations.AddRange(JsonHelper.FromJson<Conversation>(jsonTransform));
}
}
For that I made another helper script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayConversations : MonoBehaviour
{
private static ConversationTrigger conversationTrigger;
private static PlayConversations instance;
private void Awake()
{
conversationTrigger = GetComponent<ConversationTrigger>();
instance = this;
}
public static void ConversationToPlay(int index)
{
ConversationTrigger.conversationsToPlay.Add(index);
instance.StartCoroutine(conversationTrigger.PlayConversations());
}
}
And a script for testing :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeginningCutscene : MonoBehaviour
{
public DepthOfField dephOfField;
// Update is called once per frame
void Update()
{
if (dephOfField.dephOfFieldFinished == true)
{
PlayConversations.ConversationToPlay(0);
PlayConversations.ConversationToPlay(1);
}
}
}
But it's start playing first the conversation at index 1 then only part of conversation at index 0 and then start over again then ending.
I think your issue has to do with the way you implemented the ConversationsToPlay method. At each call of the method you start a new coroutine which in turn will call the PlayConversation method. What this means is that each call of ConversationToPlay will play the conversation at the index you passed and that is why they are overlapping.
The simplest solution I can think of is to move the start of the coroutine outside of the ConversationsToPlay method.
Something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayConversations : MonoBehaviour
{
private static ConversationTrigger conversationTrigger;
private static PlayConversations instance;
private void Awake()
{
conversationTrigger = GetComponent<ConversationTrigger>();
instance = this;
}
public static void AddConversationToPlay(int index)
{
ConversationTrigger.conversationsToPlay.Add(index);
}
public static void StartPlayConversationsCoroutine()
{
instance.StartCoroutine(conversationTrigger.PlayConversations());
}
}
and the test script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeginningCutscene : MonoBehaviour
{
public DepthOfField dephOfField;
// Update is called once per frame
void Update()
{
if (dephOfField.dephOfFieldFinished == true)
{
PlayConversations.AddConversationToPlay(0);
PlayConversations.AddConversationToPlay(1);
PlayConversations.StartPlayConversationsCoroutine();
}
}
}
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?