Basic purchase system in Unity3d - c#

In my game exists a opportunity to obtain a COIN, with a certain amount it is possible to release new skins.
Currently the coin score, are being stored correctly.
I have UI canvas where there skins options, I want to know how to do to be purchased these skins if the player has enough coins, or that nothing happens if it does not have enough.
Follow the codes below.
CoinScore
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BeeCoinScore: MonoBehaviour
{
public static BeeCoinScore instance;
public static int coin = 0;
public int currentCoin = 0;
string highScoreKey = "totalCoin";
Text CoinScore; // Reference to the Text component.
void Awake ()
{
// Set up the reference.
CoinScore = GetComponent <Text> ();
}
void Start(){
//Get the highScore from player prefs if it is there, 0 otherwise.
coin = PlayerPrefs.GetInt(highScoreKey, 0);
}
public void AddBeeCoinScore (int _point) {
coin += _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
void Update ()
{
// Set the displayed text to be the word "Score" followed by the score value.
CoinScore.text = "Bee Coins: " + coin;
}
void OnDisable(){
//If our scoree is greter than highscore, set new higscore and save.
if(coin>currentCoin){
PlayerPrefs.SetInt(highScoreKey, coin);
PlayerPrefs.Save();
}
}
}
Script to add points to CoinScore
using UnityEngine;
using System.Collections;
public class BeeCoin : MonoBehaviour {
public int point;
private float timeVida;
public float tempoMaximoVida;
private BeeCoinScore coin;
AudioSource coinCollectSound;
void Awake() {
coin = GameObject.FindGameObjectWithTag ("BeeCoin").GetComponent<BeeCoinScore> () as BeeCoinScore;
}
// Use this for initialization
void Start () {
coinCollectSound = GameObject.Find("SpawnControllerBeeCoin").GetComponent<AudioSource>();
}
void OnCollisionEnter2D(Collision2D colisor)
{
if (colisor.gameObject.CompareTag ("Bee")) {
coinCollectSound.Play ();
coin.AddBeeCoinScore (point);
Destroy (gameObject);
}
if (colisor.gameObject.tag == "Floor") {
Destroy (gameObject, 1f);
}
}
}
My UI canvas SHOP It's pretty basic, it has 4 images related skins, with price: 100, 200, 300 and 400 coins, 4 buttons to buy below each image, and a button to leave.
C# if possible.

I solve my problem.
On the "buy" button have attached the script BuySkin
And the script BeeCoinScore i added TakeBeeScore,
deleted: if (coin> current Coin) {}, into the void OnDisable
Now it is working perfectly.
BuySkin Script.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class BuySkin : MonoBehaviour {
public int price;
public void OnClick()
{
if (BeeCoinScore.coin >= price) {
BeeCoinScore.coin -= price;
Debug.Log ("New skin added");
}
if (BeeCoinScore.coin < price) {
Debug.Log ("Need more coins!");
}
}
}
BeeCoinScore script.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BeeCoinScore: MonoBehaviour
{
public static BeeCoinScore instance;
public static int coin = 0;
public int currentCoin = 0;
string totalCoinKey = "totalCoin";
Text CoinScore; // Reference to the Text component.
void Awake ()
{
// Set up the reference.
CoinScore = GetComponent <Text> ();
}
public void Start(){
//Get the highScore from player prefs if it is there, 0 otherwise.
coin = PlayerPrefs.GetInt(totalCoinKey, 0);
}
public void AddBeeCoinScore (int _point) {
coin += _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
public void TakeBeeCoinScore (int _point) {
coin -= _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
void Update ()
{
// Set the displayed text to be the word "Score" followed by the score value.
CoinScore.text = "Bee Coins: " + coin;
}
void OnDisable(){
PlayerPrefs.SetInt(totalCoinKey, coin);
PlayerPrefs.Save();
}
}

Related

OnTriggerExit2D getting called unnecessarily

I hope you all are doing well. I have been following a Unity tutorial for a rhythm game and I have found this bug that I could not get past. Essentially, my OnTriggerExit2D is getting called too early. I'll include a picture in the conclusion of this post. I have tried logging the game object and it seems that all of my button objects suffer the same fate. I have included a link of the tutorial that I have been following in the conclusion. Any help towards figuring this out would be helpful.
Tutorial Link: https://www.youtube.com/watch?v=PMfhS-kEvc0&ab_channel=gamesplusjames
What my game looks like, the missed shows up when I've hit it.
Debug Output
GameManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public AudioSource theMusic;
public bool startPlaying;
public BeatScroller theBS;
public static GameManager instance;
public int currentScore;
public int scorePerNote = 100;
public int scorePerGoodNote = 125;
public int scorePerPerfectNote = 150;
public int currentMultiplier;
public int multiplierTracker;
public int [] multiplierTresholds;
public Text scoreText;
public Text multiText;
// Start is called before the first frame update
void Start()
{
instance = this;
scoreText.text = "Score: 0";
multiText.text = "Multiplier: x1";
currentMultiplier = 1;
}
// Update is called once per frame
void Update()
{
if(!startPlaying){
if(Input.anyKeyDown){
startPlaying = true;
theBS.hasStarted = true;
theMusic.Play();
}
}
}
public void NoteHit(){
Debug.Log("Note Hit On Time");
if(currentMultiplier-1 < multiplierTresholds.Length){
multiplierTracker++;
if(multiplierTresholds[currentMultiplier-1] <= multiplierTracker){
multiplierTracker = 0;
currentMultiplier++;
}
}
multiText.text = "Multiplier: x"+currentMultiplier;
//currentScore += scorePerNote * currentMultiplier;
scoreText.text = "Score: "+currentScore;
}
public void NormalHit(){
currentScore += scorePerNote * currentMultiplier;
NoteHit();
}
public void GoodHit(){
currentScore += scorePerGoodNote * currentMultiplier;
NoteHit();
}
public void PerfectHit(){
currentScore += scorePerPerfectNote * currentMultiplier;
NoteHit();
}
public void NoteMissed(){
Debug.Log("MISSED!");
multiText.text = "Multiplier: x1";
}
}
BeatScroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeatScroller : MonoBehaviour
{
public float beatTempo;
public bool hasStarted;
// Start is called before the first frame update
void Start()
{
beatTempo = beatTempo / 60f;
}
// Update is called once per frame
void Update()
{
if(!hasStarted){
}else{
transform.position -= new Vector3(0f, beatTempo*Time.deltaTime, 0f);
}
}
}
ButtonController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonController : MonoBehaviour
{
// Start is called before the first frame update
private SpriteRenderer theSR;
public Sprite defaultImage;
public Sprite pressedImage;
public KeyCode keyToPress;
void Start()
{
theSR = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(keyToPress))
{
theSR.sprite = pressedImage;
}
if(Input.GetKeyUp(keyToPress))
{
theSR.sprite = defaultImage;
}
}
}
noteObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class noteObject : MonoBehaviour
{
public bool canBePressed;
public KeyCode KeyToPress;
public GameObject hitEffect, goodEffect, perfectEffect, missedEffect;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyToPress))
{
if(canBePressed)
{
gameObject.SetActive(false);
if(Mathf.Abs(transform.position.y) > 0.25){
GameManager.instance.NormalHit();
Debug.Log("Normal Hit!");
Instantiate(hitEffect,transform.position, hitEffect.transform.rotation);
}else if(Mathf.Abs(transform.position.y) > 0.05f){
GameManager.instance.GoodHit();
Debug.Log("Good Hit!!");
Instantiate(goodEffect,transform.position, goodEffect.transform.rotation);
}else{
GameManager.instance.PerfectHit();
Debug.Log("PERFECT HIT!!!");
Instantiate(perfectEffect,transform.position, perfectEffect.transform.rotation);
}
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Activator")
{
canBePressed = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "Activator")
{
Debug.Log("Exited collider on game object: "+ other.gameObject.name);
canBePressed = false;
GameManager.instance.NoteMissed();
Instantiate(missedEffect,transform.position, missedEffect.transform.rotation);
}
}
}
EffectObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EffectObject : MonoBehaviour
{
public float lifeTime = 1f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Destroy(gameObject, lifeTime);
}
}
Hmm ... You say that OnTriggerExit2D is called to early? I assume it's called when the elements are still inside one another? If that's the case I guess your bounding boxes don't have the right size, or the right shape. I see arrows, do they have a rectangular bounding box or a polygon one that follows their shape? Are all your bounding boxes the right size?
I figured out what was wrong thanks to AdrAs's comment.
Turns out I had to check the y position of my arrow and collider were well enough below the height of my button box collider. In addition to that, I reshaped my colliders. I found that this code did the trick for me. Thank You All For the Nudges in the right direction.
noteObject -> new OnTriggerExit2D
private void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "Activator" && transform.position.y < -0.32)
{
Debug.Log("Exited collider on game object: "+ other.gameObject.name);
canBePressed = false;
GameManager.instance.NoteMissed();
Instantiate(missedEffect,transform.position, missedEffect.transform.rotation);
}
}

Saving the score, then using it in highscore

I have a script that gives you 1 point every 1 second.
I was wondering how to save the score as a high score. I know about PlayerPref, but I can't get my head around it. I've also tried out several other explanations.
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class score : MonoBehaviour
{
private Text scoreText;
private float PIPS;
public GameObject gameOverScore;
public GameObject Player;
public static float scoreAmount;
public void Start()
{
scoreText = GetComponent<Text>();
scoreAmount = 0.0f;
PIPS = 1.0f;
}
public void Update()
{
if (Player.activeInHierarchy == true)
{
scoreText.text = scoreAmount.ToString("F0");
scoreAmount += PIPS * Time.deltaTime;
}
else
{
scoreText.enabled = false;
gameOverScore.GetComponent<TextMeshProUGUI>().text = scoreAmount.ToString("F0");
}
}
}
Here is an Instance from one of my Scripts -->
int HighScore = PlayerPerfs.GetInt("HighScore", 0) //If playing First Time Score = 0
void Save()
{
if(ScoreUpdate.CurrentScore > HighScore) //Check if CurrentScore is more than HighScore
{
PlayerPrefs.SetInt("HighScore", ScoreUpdate.CurrentScore);//Save New High Score
}
}
You Now Just Need To Call This Function Save() whenever the Game get complete or player dies (if dies at any point)
Edit : Replace Your Variables on place of ScoreUpdate
While this is not the ideal way, you can use playerprefs on Awake and OnDisable().
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class score : MonoBehaviour
{
private Text scoreText;
private float PIPS;
public GameObject gameOverScore;
public GameObject Player;
public static float scoreAmount;
public float HighScore;
public void Start()
{
scoreText = GetComponent<Text>();
scoreAmount = 0.0f;
PIPS = 1.0f;
}
private void OnDisable()
{
// this will save the highscore in playerprefs when the game ends[application quit].
PlayerPrefs.SetFloat("HighScore", HighScore);
}
private void Awake()
{
// this will load the highscore from playerprefs
HighScore = PlayerPrefs.GetFloat("HighScore");
}
public void Update()
{
if (Player.activeInHierarchy == true)
{
scoreText.text = scoreAmount.ToString("F0");
scoreAmount += PIPS * Time.deltaTime;
if (scoreAmount > HighScore)
{
HighScore = scoreAmount;
}
}
else
{
scoreText.enabled = false;
gameOverScore.GetComponent<TextMeshProUGUI>().text = scoreAmount.ToString("F0");
}
}
}
let me know if this helps.

Unity Quiz Game Score in C#

I am making a quiz game in the unity from the unity live session quiz game tutorials everything is working fine except somehow the score isn't working when i Click the button it should add 10 score to the Score. Here are the tutorials : https://unity3d.com/learn/tutorials/topics/scripting/intro-and-setup?playlist=17117 and the code for my Game Controller :
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
public class GameController : MonoBehaviour {
public Text questionDisplayText;
public Text scoreDisplayText;
public Text timeRemainingDisplayText;
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;
public GameObject questionDisplay;
public GameObject roundEndDisplay;
private DataController dataController;
private RoundData currentRoundData;
private QuestionData[] questionPool;
private bool isRoundActive;
private float timeRemaining;
private int questionIndex;
private int playerScore;
private List<GameObject> answerButtonGameObjects = new List<GameObject>();
// Use this for initialization
void Start ()
{
dataController = FindObjectOfType<DataController> ();
currentRoundData = dataController.GetCurrentRoundData ();
questionPool = currentRoundData.questions;
timeRemaining = currentRoundData.timeLimitInSeconds;
UpdateTimeRemainingDisplay();
playerScore = 0;
questionIndex = 0;
ShowQuestion ();
isRoundActive = true;
}
private void ShowQuestion()
{
RemoveAnswerButtons ();
QuestionData questionData = questionPool [questionIndex];
questionDisplayText.text = questionData.questionText;
for (int i = 0; i < questionData.answers.Length; i++)
{
GameObject answerButtonGameObject = answerButtonObjectPool.GetObject();
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
AnswerButton answerButton = answerButtonGameObject.GetComponent<AnswerButton>();
answerButton.Setup(questionData.answers[i]);
}
}
private void RemoveAnswerButtons()
{
while (answerButtonGameObjects.Count > 0)
{
answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
answerButtonGameObjects.RemoveAt(0);
}
}
public void AnswerButtonClicked(bool isCorrect)
{
if (isCorrect)
{
playerScore += currentRoundData.pointsAddedForCorrectAnswer;
scoreDisplayText.text = "Score: " + playerScore.ToString();
}
if (questionPool.Length > questionIndex + 1) {
questionIndex++;
ShowQuestion ();
} else
{
EndRound();
}
}
public void EndRound()
{
isRoundActive = false;
questionDisplay.SetActive (false);
roundEndDisplay.SetActive (true);
}
public void ReturnToMenu()
{
SceneManager.LoadScene ("MenuScreen");
}
private void UpdateTimeRemainingDisplay()
{
timeRemainingDisplayText.text = "Time: " + Mathf.Round (timeRemaining).ToString ();
}
// Update is called once per frame
void Update ()
{
if (isRoundActive)
{
timeRemaining -= Time.deltaTime;
UpdateTimeRemainingDisplay();
if (timeRemaining <= 0f)
{
EndRound();
}
}
}
}
and my answer Button Code:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class AnswerButton : MonoBehaviour {
public Text answerText;
private AnswerData answerData;
private GameController GameController;
// Use this for initialization
void Start ()
{
GameController = FindObjectOfType<GameController> ();
}
public void Setup(AnswerData data)
{
answerData = data;
answerText.text = answerData.answerText;
}
public void HandleClick()
{
GameController.AnswerButtonClicked (answerData.isCorrect);
}
}
and Answer Data :
using UnityEngine;
using System.Collections;
[System.Serializable]
public class AnswerData
{
public string answerText;
public bool isCorrect;
}
If everything is working fine (the whole code gets executed correctly, which I presume at this point), you probably did not set the data correctly. In your Game Controller, you have the line
playerScore += currentRoundData.pointsAddedForCorrectAnswer;
in your AnswerButtonClicked method which should add an amount you defined to the score if the answer is correct. Since I presume that your whole code is running fine (I can't see your in-engine setup, only the code here, which looks like the one in the tutorial), this is probably the first location where to look at the error. This value is probably set in the Unity Inspector or via another script, so you may want to go check in other files or the Editor.
The next thing to check is, if the buttons are correctly linked via their event handler. This can be checked by looking at the inspector. In the tutorial series this step is done in part Click to answer at the end of the video.

Accessing a variable from player prefs in another scene

I'm managing my HighScore in my scene "Standard Game" by using playerprefs
I need to access my variable HighScore in my other script "SaveTest" which is in a different scene called "Main Menu" So i can destroy objects tagged DestroyUI when a highscore is reached.
Ive been googling for a bit but im not sure what im doing wrong.
Save Test
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveTest : MonoBehaviour
{
public ButtonReposition buttonrepositionscript;
void Start()
{
DontDestroyOnLoad(gameObject);
GameObject obj = GameObject.Find("ButtonReposition");
}
// Update is called once per frame
void Update()
{
if (GetComponent<ButtonReposition.highscore <= 100)
Destroy(GameObject.FindWithTag("DestroyUI"));
}
}
HighScore script
public class ButtonReposition : MonoBehaviour
{
public Button prefab;
public GameObject loseObject;
public int count;
public int highscore;
public Text countText;
public Text Highscoretext;
public Image lineimagestandard;
// Use this for initialization
void Start()
{
PlayerPrefs.GetInt("scorePref");
highscore = PlayerPrefs.GetInt("scorePref");
SetHighscoretext();
SetCountText();
float x = Random.Range(325f, -600f);
float y = Random.Range(250f, -450f);
Debug.Log(x + "," + y);
prefab.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
}
void Update()
{
if (Highscoretext.name == "highscoretext")
{
Highscoretext.text = "highscore" + highscore;
}
PlayerPrefs.SetInt("scorePref", highscore);
}
put this on your Save Test script highscore = PlayerPrefs.GetInt("scorePref");
and that's it.

Reseting a level in unity when exit to menu is hit

I have a pause screen in my game having two buttons : resume game and exit to main menu
The main menu have only 1 button wish is play,
when i click on exit to main menu the main menu level is loaded,if then i click Play My game level scene is not restarting but continuing everything,having all it's pre created prefabs and all its game object.
How should I fix this particular bug and restarting the game when exit to main menu is clicked
Exit to Menu Button :
void OnMouseDown() {
PauseGame.isPause=false;
Application.LoadLevel("MainMenu");
}
Play button :
void OnMouseDown() {
spriteRenderer.sprite = s2;
Application.LoadLevel("Game");
}
I have three Prefabs:
Turret :
using UnityEngine;
using System.Collections;
public class Turret : MonoBehaviour {
// Use this for initialization
double LastBallTime=0.0;
double LastTurretMovingTime=0.0;
public double spawnballTime=1.5;
public double StartTurretMovingTime=35.0;
public double BallCount=2;
public bool IsRed=false;
public GameObject BallPrefab;
public GameObject RedBallPrefab;
Vector2 v ;
void Start () {
}
// Update is called once per frame
void Update () {
if (Time.time > LastBallTime + spawnballTime) {
LastBallTime=Time.time;
int rand= Random.Range(1,6);
if(rand>=1 && rand<=4)
Instantiate(BallPrefab, transform.position, transform.rotation) ;
else{
Instantiate(RedBallPrefab, transform.position, transform.rotation) ;
}
}
if (Time.time > LastTurretMovingTime + StartTurretMovingTime) {
LastTurretMovingTime=Time.time;
int x = Random.Range (-2,3);
int y = Random.Range (-3,3);
v = new Vector3 (x, y,0);
gameObject.transform.position=v;
}
}
void OnBecameInvisible ()
{
Destroy(gameObject);
}
}
BALL :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Ball : MonoBehaviour {
// Use this for initialization
public static double Killed=0;
public Text ScoreTextPrefab;
GameObject ParentCanvas;
void Start () {
ParentCanvas = GameObject.Find ("Canvas");
}
void OnMouseDown() {
if (!PauseGame.isPause) {
Text t = Instantiate (ScoreTextPrefab, transform.position, transform.rotation) as Text;
t.transform.SetParent (ParentCanvas.transform, false);
if (gameObject.name.Contains ("RedBall")) {
t.text = "O o P s";
RedKilled++;
} else {
Killed++;
}
Object.Destroy (gameObject);
}
}
// Update is called once per frame
void Update () {
}
void OnBecameInvisible ()
{
Destroy(gameObject);
}
}
TurretBall manager wish is assigned for the main camera of the game scene :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class TurretBallManager : MonoBehaviour {
// Use this for initialization
public GameObject TurretPrefab;
public double turretSpawnTime=35;
public double LastTurretTime=0;
public double MaxTurret=10;
int currentTurretCount=1;
public Text Killedtxt;
Vector2 v;
void Start () {
v = new Vector2(0,2);
Instantiate (TurretPrefab, v, Quaternion.identity);
}
void CreateTurret()
{
if (Time.time > LastTurretTime + turretSpawnTime) {
LastTurretTime=Time.time;
currentTurretCount++;
if(currentTurretCount>1)
v.x=TurretPrefab.transform.position.x-currentTurretCount/2;
if(currentTurretCount<=MaxTurret){
Instantiate(TurretPrefab,v,Quaternion.identity);
}
}
}
// Update is called once per frame
void Update () {
Killedtxt.text = "Kill : " + Ball.Killed;
CreateTurret ();
}
}

Categories