I want to set the a score to zero whenever a certain button is pressed.
This is the script I made:
public class zeroOut : MonoBehaviour
{
private Rigidbody2D rb;
void OnMouseDown()
{
scoreScript.scoreValue -= scoreScript.scoreValue;
}
}
This is the scoreScript:
public class scoreScript : MonoBehaviour
{
public static int scoreValue = 0;
Text score;
// Start is called before the first frame update
void Start()
{
score = GetComponent<Text> ();
}
// Update is called once per frame
void Update()
{
score.text = "" + scoreValue;
}
}
Have you got any suggestions?
Related
I am a newbie and I am making this android game that if the player has destroyed a meteor, a score is added to its score, well the problem is that I want to display the score in my scoreText, but whenever I initialize it in my Update(), it rapidly adds the score in my scoreText. I just cant figure out how to properly add the score to my scoreText This is my game manager script
public class GameManager : MonoBehaviour
{
public static int displayScores;
public int displayTheScore;
public Text scoreText;
// Start is called before the first frame update
void Start()
{
scoreText.text = "" + displayScores;
}
void Update(){
scoreText.text = "" + displayScores;
displayScores += Meteor.displayScore;
}
}
And this is the script to making the conditions that if the meteor is detroyed, a score is added to displayScore depending on the hits to the meteor
public class Meteor : MonoBehaviour
{
public int maxHealth;
public int currentHealth;
public float speed;
public int hits = 0;
public int score = 100;
public static int displayScore;
public int display;
public int currentHealthChecker;
public static int counter;
public Health healthBar;
public GameObject canvas;
public Transform effect;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.setMaxHealth(maxHealth);
}
// Update is called once per frame
void Update()
{
transform.Translate(Vector2.down * speed * Time.deltaTime);
}
public void OnTriggerEnter2D(Collider2D other){
if(other.transform.tag == "bullet"){
hits++;
canvas.SetActive(true);
currentHealth--;
currentHealthChecker = currentHealth;
healthBar.setHealth(currentHealth);
display = displayScore;
if(currentHealth <= 0){
displayScore = score * hits;
Instantiate(effect, other.transform.position, other.transform.rotation);
Destroy(this.gameObject);
counter++;
canvas.SetActive(false);
}
Destroy(other.gameObject);
}
if(other.transform.tag == "bottom"){
Destroy(this.gameObject);
}
}
}
you are initializing in update method, that why it keeps adding rapidly because update is called every frame. instead of adding in update, add the score value in ontriggerenter2d method.
public void OnTriggerEnter2D(Collider2D other){
if(other.transform.tag == "bullet"){//add score}
Im making a endless runner game and am using a 'ScoreManager' object with a box collider 2d set to 'is trigger' increasing the score every time a object hits it. But I want it to stop increasing the score if the health reaches 0. This is the ScoreManager code:
public int score;
public Text scoreDisplay;
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Obstacle"))
{
score++;
}
}
private void Update()
{
scoreDisplay.text = score.ToString();
}
I would like to add a:
public int health = 3;
and in the Update function:
if (health <= 0) {
Destroy(gameObject);
}
But that doesn't seem to work.
The health is displayed in a player script.
public class Player : MonoBehaviour
{
private Vector2 targetPos;
public float Yincrement;
public float speed;
public float maxHeight;
public float minHeight;
public Text healthDisplay;
public GameObject gameOver;
public int health = 3;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
private void Update()
{
healthDisplay.text = health.ToString();
if (health <= 0) {
gameOver.SetActive(true);
Destroy(gameObject);
}
Any thoughts?
Wherever your health is defined, substitute it by a property that launches an event whenever set to a value < 0. Like this:
public class Player : MonoBehavior
{
public delegate void PlayerDiedDelegate();
public static event PlayerDiedDelegate onPlayerDied;
private int _health;
public int health
{
get
{
return _health;
}
set
{
_health = value;
if(_health < 0)
{
onPlayerDied?.Invoke();
}
}
}
}
Now you can attach any controller in your scene to the event:
public class ScoreController : MonoBehavior
{
private void Awake()
{
Player.onPlayerDied += OnPlayerDied;
}
private void OnPlayerDied()
{
// Put your logic here: stop collecting score etc.
}
}
Once the player dies and starts the game, the score is not resetting and staying as the previous score. I would like the score to reset once the player dies or leaves the game. How do you do this?
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
Text score;
// Use this for initialization
void Start () {
score = GetComponent<Text>();
}
// Update is called once per frame
void Update () {
score.text = "Score: " + scoreValue;
}
}
score.text is storing the evaluated value of Score: and whatever is stored in scoreValue at the time Update() is called. None of your code ever updates scoreValue from what you've shown.
Also be aware of scoreValue being static, be sure that accurately reflects your intention (e.g. is scoreValue a property of the ScoreScript class or each instance of it?). Note that score is not static, and I would expect both of those to have the same behavior (either both static or not).
i.e. something like
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
Text score;
// Use this for initialization
void Start () {
score = GetComponent<Text>();
}
// Update is called once per frame
void Update () {
score.text = "Score: " + scoreValue;
}
void ScoreReset() {
scoreValue = 0;
}
void AddPoints(int points) {
scoreValue += points;
}
}
If you load the scene after player die scoreValue will be 0 cause as I see that you assign 0 in your above code.
In the game I am creating a 'Game Over' scene which loads once the player loses the game. During the game, the score is counted by the player's position on the screen and increases as the player's y-axis position increases.
I used this code to display the score on the scene the game was actually played:
using UnityEngine;
using UnityEngine.UI;
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
}
}
I tried to use the same coding to display the final score of the player on the 'Game Over' screen. The problem I faced was that I was not able to identify the player on the 'Game Over' scene as the player was not an object or sprite on that scene.
Is there an easy way to reference the player sprite from the previous scene into the final ('Game Over') scene so I can use it to determine the final score?
This is the script I tried with a game object of the 'EndScene' within the playing scene:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class EndMenu: MonoBehaviour
{
public Text scoreText;
public Transform player;
public static bool GameEnds = false;
public GameObject endMenuUI;
void OnCollisionEnter2D(Collision2D exampleCol)
{
if(exampleCol.collider.tag == "Obstacle")
{
endMenuUI.SetActive(true);
Time.timeScale = 0.0001f;
GameEnds = true;
}
}
public void Retry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
SceneManager.LoadScene("Menu");
}
public void Quit()
{
Debug.Log("Quitting game...");
Application.Quit();
}
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
}
}
You can keep the player using DontDestroyOnLoad
You could add this to the player:
void Awake() {
DontDestroyOnLoad(transform.gameObject);
}
You could do other stuff like keeping just the data... but the easier way should be this one.
Keep in mind that the player will remain in you gameover screen.
In my opinion the best idea could be creating a new gameobject in your game scene called "GameOverScreen" and disable it until you need it.
I think the easiest solution would be to simply store the score as a static variable that will persist across scene loads, then manually reset it when you start over. For example:
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
public static string scoreString;
// Update is called once per frame
void Update()
{
scoreString = player.position.y.ToString("0");
scoreText.text = scoreString;
}
}
Now you will be able to access scoreString from anywhere in your code and it will be whatever it was when the PlayerScore component last ran its Update(). Then in your EndMenu class, you would simply update your Retry() and BackToMenu() methods like so:
public void Retry()
{
PlayerScore.scoreString = "0";
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
PlayerScore.scoreString = "0";
SceneManager.LoadScene("Menu");
}
And your EndMenu.Update() method becomes the following:
// Update is called once per frame
void Update()
{
scoreText.text = PlayerScore.scoreString;
}
//try to use playerprefs to save the score
public class PlayerScore : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.y.ToString("0");
PlayerPrefs.SetInt("CurrentScore", player.position.y);
}
}
//for another scene get the value of saved score using playerprefs.getInt
public class EndMenu: MonoBehaviour
{
public Text scoreText;
public Transform player;
public static bool GameEnds = false;
public GameObject endMenuUI;
void OnCollisionEnter2D(Collision2D exampleCol)
{
if(exampleCol.collider.tag == "Obstacle")
{
endMenuUI.SetActive(true);
Time.timeScale = 0.0001f;
GameEnds = true;
}
}
public void Retry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void BackToMenu()
{
SceneManager.LoadScene("Menu");
}
public void Quit()
{
Debug.Log("Quitting game...");
Application.Quit();
}
// Update is called once per frame
void Update()
{
scoreText.text = PlayerPrefs.GetInt("Score",0);
}
}
I created a simple game in which the player collides with the enemy, and the score will increase by one. How to do it correctly?
Below is my code:
public class Bird : MonoBehaviour {
public GameObject deathparticales;
public Vector2 velocity = new Vector2(-2, 0);
public float range = 5;
public int score;
private string scoreText;
// Use this for initialization
void Start()
{
score = 0;
rigidbody2D.velocity = velocity;
transform.position = new Vector3(transform.position.x, transform.position.y - range * Random.value, transform.position.z);
}
// Update is called once per frame
void Update () {
// Die by being off screen
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.x < -10)
{
Die();
}
scoreText = "Score: " + score.ToString();
}
void OnGUI ()
{
GUI.color = Color.black;
GUILayout.Label(scoreText);
}
// Die by collision
void OnCollisionEnter2D(Collision2D death)
{
if(death.transform.tag == "Playercollision")
{
score++;
Destroy(gameObject);
Instantiate(deathparticales,transform.position,Quaternion.identity);
}
}
void Die()
{
Application.LoadLevel(Application.loadedLevel);
}
}
Problem
You were trying to update the score inside everyone of those Birds.
Solution
You need a class whose only purpose is to handle the score.
public class ScoreManager : MonoBehaviour
{
private int score = 0;
private static ScoreManager instance;
void Awake()
{
instance = this;
}
public void incrementScore(int amount)
{
score += amount;
}
public static ScoreManager getInstance()
{
return instance;
}
void OnGUI ()
{
string scoreText = "Score: " + score.ToString();
GUI.color = Color.black;
GUILayout.Label(scoreText);
}
}
Then every time you want to update the score you call ScoreManager from another class, like this:
ScoreManager.getInstance().incrementScore(10);
If all the code is from same script, the problem is that you are increasing the score of one instance of Bird class and then killing that instance:
score++;
Destroy(gameObject);
The gameObject refers to that gameobject into which this instance of Bird class is attached to.
Score variable is just public which means that every instance of Bird has their own, but you can access the variable from other scripts. If you want to have just one score variable shared with all Birds you could make the variable static.
But if you have multiple birds, all of them are going to call OnGUI function and draw the value to the screen. So it might be better idea to change your design and move the score to some other gameObject.