LootLocker submitscore script doesnt work - c#

When the game starts, the session start script works fine, but the sending of points does not respond, the debuglog does not respond either
using LootLocker.Requests;
using UnityEngine;
public class LeaderBoard: MonoBehaviour
{
public void SubmitScore()
{
int leaderboardID = 11584;
int score = PlayerPrefs.GetInt("high");
string playerID = PlayerPrefs.GetString("PlayerID");
LootLockerSDKManager.SubmitScore(playerID, score, leaderboardID, (response) =>
{
if (response.success)
{
Debug.Log("Successfully uploaded score");
}
else
{
Debug.Log("Failed" + response.Error);
}
});
}
}
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
LeaderBoard leaderBoard;
void Update()
{
if (game.isComplete)
{
leaderBoard.SubmitScore();
}
}
objects with scripts in the game added
I tried following the official tutorial https://www.youtube.com/watch?v=u8llsk7FoYg&t=605s and i know its something supersimple but i dont know what pls help me

Related

How do I make a unity ad play every 5 rounds/losses?

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.

error CS0103: The name 'playfabManager' does not exist in the current context

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();
}

C# Unity Queue NullReferenceException

I am trying to create a simple dialogue system for my game in Unity. I've set up a special trigger for a Dialogue to start and the code is passing right variable but somehow it gets stuck at clearing the queue and throws a NullReferenceException.
I've seen through debugger that all variables and triggers work perfectly fine till cs:27 inside DialogueManager.cs. I've also checked the inspector to make sure everything is correctly assigned.
Dialogue class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
public string name;
[TextArea(3,10)]
public string[] sentences;
}
DialogueTrigger class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPC_DialogTrigger : MonoBehaviour
{
// Player
public Transform player;
// GameMaager to close
public GameObject Gameplay;
// Camera and Canvas to turn on
public GameObject DialogueManager;
// NPC Details
public GameObject InteractionNPCNameTextField;
public Transform interactionTransform;
public float radius = 3f;
private bool isBusy = false;
// DialogueStart
public GameObject DialogueStart;
void Start()
{
InteractionNPCNameTextField.gameObject.SetActive(false);
}
void Update()
{
float distance = Vector3.Distance(player.position, interactionTransform.position);
if (distance <= radius)
{
if (isBusy == false)
{
InteractionNPCNameTextField.gameObject.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
Dialogue();
Debug.Log("Started Dialogue procedure.");
}
}
}
else if (distance > radius)
{
InteractionNPCNameTextField.gameObject.SetActive(false);
}
}
public void Dialogue()
{
Gameplay.SetActive(false);
DialogueManager.SetActive(true);
DialogueStart.GetComponent<DialogueStart>().TriggerDialogue();
Debug.Log("Triggered Dialogue.");
}
void OnDrawGizmosSelected()
{
if (interactionTransform == null)
{
interactionTransform = transform;
}
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(interactionTransform.position, radius);
}
}
DialogueStart class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueStart : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
Debug.Log("Dialogue sent to dialogue manager.");
}
}
DialogueManager class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DialogueManager : MonoBehaviour
{
public Text nameText;
public Text DialogueText;
private Queue<string> sentences;
public GameObject DialogueManagerUI;
void Start()
{
if (sentences == null)
{
sentences = new Queue<string>();
}
}
public void StartDialogue (Dialogue dialogue)
{
Debug.Log("Received dialogues: " + dialogue);
nameText.text = dialogue.name;
Debug.Log("Start Dialogue: " + sentences.Count);
sentences.Clear();
Debug.Log("Sentences Cleared: " + sentences);
foreach (string sentence in dialogue.sentences)
{
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if(sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
DialogueText.text = sentence;
}
void EndDialogue()
{
Debug.Log("End of conversation.");
}
private void Update()
{
if (DialogueManagerUI.activeInHierarchy)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
else if (!DialogueManagerUI.activeInHierarchy)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
}
Visual Studio doesn't give me any errors.
Unity error code -> Screenshot
Debugger right before issue -> Screenshot2
Seems to me like the Queue is never assigned to sentences and it remains empty.
If it is so - why?
It sounds like DialogueManager.StartDialogue probably via DialogueStart.TriggerDialogue is called from somewhere in either Awake or at least before your Start was executed.
Especially
DialogueManager.SetActive(true);
lets assume the DialogueManager object is inactive at first anyway. So maybe your stuff is called before it is set to active.
This might also be due to the Start where you set
InteractionNPCNameTextField.gameObject.SetActive(false);
so any component on this GameObject might not have its Start method getting called. Maybe you referenced the wrong GameObject here?
Debugging would help to figure out in which order your methods get called.
In general my thumb rule for initializing is
Do everything that depends only on yourself in Awake
Do everything that depends on other components being setup already in Start
This way you can (almost) always be sure that stuff is already initialized when you need it.
However, these are only guesses but
The simple solution here:
You could already solve this by simply initializing the sentences right away using
private readonly Queue<string> sentences = new Queue<string>();
now it is definitely initialized even before Start or Awake get called!

Coin value wont save every time I run my game

I'm making a 2d game on unity, and I have a script that saves my coin value, but it doesn't save when I open the after getting more coins.
This is my script that saves the data:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Coin : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D other)
{
if(other.gameObject.tag == "Player")
{
PlayerPrefsManager.coins += 1;
PlayerPrefsManager.UpdateCoins();
}
}
}
And my script that displays the data:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CoinsDisplay : MonoBehaviour
{
private Text text;
void Start()
{
text = GetComponent<Text>();
}
void Update()
{
string[] temp = text.text.Split('X');
text.text = temp[0] + "X: " + PlayerPrefsManager.coins;
}
}
player prefs manager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerPrefsManager : MonoBehaviour
{
public const string Coins = "Coins";
public static int coins;
void Start()
{
coins = PlayerPrefs.GetInt("Coins");
}
public static void UpdateCoins()
{
PlayerPrefs.SetInt("Coins", coins);
coins = PlayerPrefs.GetInt("Coins");
PlayerPrefs.Save();
}
}
Your code should work fine, but I guess you've forgotten to assign your PlayerPrefsManager script to a gameObject. Cause if its Start doesn't execute, we will get the same result.
By the way, use your const string 'Coins', you've just declared it but you're not using it in these calls: SetInt, GetInt.
And try to update PlayerPrefs (PlayerPrefs.Save()) less often, since it writes data on the disk and is a little expensive to do it each time your coin's value changes. You can have a method called 'save' on your prefManager to only get called when you're done with the level, mission is complete etc... , or if you don't want to lose the data, call it less often, like once in each 10 seconds (take a look at Invokerepeating)

How to assign a death counter to a Text Mesh on Unity?

I'm trying to do a 2D platformer with a deaths counter, but I'm facing a problem.
Here is the script I attached to a 3D Text:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeathCounter : Respawn
{
public Text DeathCount;
public void SetText(int text)
{
string deathsS = deaths.ToString();
DeathCount.text = deathsS;
}
}
And it does nothing.
I'm asking for help please.
What do I do ?
Here is the "Respawn" script, if needed:
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
public class Respawn : MonoBehaviour
{
public int deaths;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
Thanks a lot for your help !
Have a nice day.
First thing I would do is remove the inheriting of Respawn from your DeathCounter class since it's not extending the functionality of Respawn. I would then set the function to use the passed in parameter to set the text value instead.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeathCounter : MonoBehaviour
{
public Text DeathCount;
public void SetText(String text)
{
DeathCount.text = "Death Count: " + text;
}
}
Then, in your other class when doing your collision check you can pass the death count value as what to set your DeathCount text to.
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
public class Respawn : MonoBehaviour
{
public int deaths;
//Reference to your DeathCounter script
public DeathCounter dCounter;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
//New line here, with passed in script for updating as a reference
dCounter.SetText(deaths.ToString());
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
Edit: One script version...
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Respawn : MonoBehaviour
{
public int deaths;
//Reference to your Text, dragged in via the inspector
public Text deathCount;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
//Just update the referenced UI text
deathCount.text = "Death Count: " + deaths;
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
The problem
basically lies in the LoadScene:
You increase the deaths value BUT then you reload the scene &rightarrow; you also reload the Respawn instance and therefore deaths again will have its original value so probably 0.
You didn't even call the SetText method but even if you would when the scene is reloaded also the Text component is reloaded and will have the original text like of you hadn't called the SetText method at all.
Solution
I'm order to fix it in this case I would use
public class Respawn : MonoBehaviour
{
public static int deaths{ get; private set; }
...
if the value is static it is not bound to a certain instance of Respawn but "lives" directly in the type Respawn. Therefore it keeps its current value also when reloading the scene. The {get; private set;} turns it from a field into a property which can be read by every other class but written only by the Respawn class.
Further you never want to use something like
System.Threading.Thread.Sleep(500);
in the Unity main thread. This completely freezes the main thread and if you e.g. later add any animations etc the app will simply freeze completely. Instead use a Coroutine like
void OnCollisionEnter2D(Collision2D col)
{
if(!col.transform.CompareTag("Player")) return;
deaths += 1;
Debug.Log("You are dead");
StartCoroutine(Reload());
}
private IEnumerator Reload()
{
yield return new WaitForSeconds(0.5f);
SceneManager.LoadScene(0);
}
Finally you have to set the Text after loading the scene so it gets updated also in the reloaded scene.
public class DeathCounter : Respawn
{
public Text DeathCount;
// automatically called when scene is reloaded
private void OnEnable()
{
DeathCount.text = deaths.ToString();
}
}
Sidenote:
In Respawn you store a
scene = SceneManager.GetActiveScene();
but later never use it but instead anyway use
SceneManager.LoadScene(0);
so I would get rid of that Start method .. it only causes unnecessary overhead.

Categories

Resources