- Home /
How to add a score value smoothly ?
Okay so I have my score. And collectibles which have 500 points each
I want them to count smoothly, like 001 002 ... 499 500 (like so but faster of course :) ) But for now i just have instant count which adding the score.
Please help me on this, here is my script of ScoreManager.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ScoreManager : MonoBehaviour {
Animator anim;
public static int score;
TextMeshProUGUI text;
public static bool collected;
public float min;
public float max;
public float t;
void Awake()
{
text = GetComponent<TextMeshProUGUI> ();
score = 0;
}
void Start()
{
anim = GetComponent<Animator> ();
collected = false;
}
void Update () {
text.text = score + " PTS";
if (score > 0)
{
anim.SetBool ("Points", true);
}
if (collected == true) {
t = Time.time;
text.fontSize = Mathf.Lerp (min, max, t);
collected = false;
} else {
t = Time.time;
text.fontSize = Mathf.Lerp (max, min, t);
}
}
}
And the second which is on my Collectible objects:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collectibles : MonoBehaviour {
public int scoreValue;
public bool alreadyScored;
void OnTriggerEnter2D (Collider2D col) {
if (col.gameObject.layer == LayerMask.NameToLayer ("Player")) {
if (alreadyScored)
return;
alreadyScored = true;
ScoreManager.score += scoreValue;
ScoreManager.collected = true;
} else {
ScoreManager.collected = false;
}
}
}
Is your question how to animate the score text so that receiving points it quickly counts up to the point value (500 in this case)?
$$anonymous$$y collectibles add 500 points But I hope I can find the resolve for any point number count receiving
Answer by Pangamini · Feb 09, 2018 at 09:15 AM
How about this? When you collect, you add the score yo your manager instantly (because that's what logically happens, your score is already there). If I get it right, all you want is to display the value growing smoothly. S my suggestion is:
Collectibles add score instantly (and can be immediately destroyed
ScoreManager holds the absolute / real score in one var (let's say int score)
ScoreManager holds the smoothed value, which will be float (for extra smoothness, call it float smoothScore)
Now, what you display in your text field / progress bar / wherever you want, is the smoothScore. The job of the scoreManager is to slowly move the smoothScore towards the value of score in some way. You may want to just increase it by some constant (*deltaTime) , but that means the time it takes to reach the target value can be very long or very short. I'd suggest using Mathf.SmoothDamp, where you will simply tell it how long (approximately) you want the transition to take, no matter how far is the real score from the smooth value. Using smoothdamp means you have to have another float value, call it smoothScoreVelocity, and that is a smoothing value used by the SmoothDamp (passed in as ref argument) and you dont' otherwise have to touch it.
Now the advantages of this system are: It's really simple and self-contained (the source of the score, the collectible does not contribute to smoothing) It's really safe (in terms of managing how much score do you really have at any exact time, you won't get any errors)
I hope this makes sense and it helps
Okay, i understand what you mean by this But hot to implement this to the script? I need to make my score a string and make it raise by deltaTime? try to make an example code for me please
Well I think I described it pretty much exactly. But here's something like a code (that I didn't try to compile)
public int score;
private float m_smoothScore;
private float m_smoothScoreVelocity;
private int m_displayedScore = -1;
Text$$anonymous$$eshProUGUI scoreLabel;
void Update()
{
// smooth score animation
m_smoothScore = $$anonymous$$athf.SmoothDamp(m_smoothScore, (float)score, ref m_smoothScoreVelocity, 0.2f, $$anonymous$$athf.Infinity, Time.deltaTime);
// display the text
int toDisplay = (int)$$anonymous$$athf.Round(m_smoothScore);
if(toDisplay != m_displayedScore)
{
m_displayedScore = toDisplay;
text.text = "Score: "+m_smoothScore;
}
}
Now notice one more thing, I've added m_displayedScore and I am checking if it's been changed. It's to reduce the string generation process, as it allocates garbage, and now it's skippe when the string generated would be the same anyway.
Also, when you try to add the score by some collectible, you just add it all at once ( eg. score += 50 ), don't do any smoothing in the coin itself
Okay, so I added changes to my script, and it works, but it shows numbers with after the comma (like this - 499,985) And I have only two problems now :) How to make in show only numbers before comma (like - 500) And the second how to make it count for 500, not 499? I adding the script that I made by your instruction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using T$$anonymous$$Pro;
public class Score$$anonymous$$anager : $$anonymous$$onoBehaviour {
Animator anim;
public static int score;
private float m_smoothScore;
private float m_smoothScoreVelocity;
private int m_displayedScore = -1;
Text$$anonymous$$eshProUGUI text;
public static bool collected;
public float $$anonymous$$;
public float max;
public float t;
void Awake()
{
text = GetComponent<Text$$anonymous$$eshProUGUI> ();
score = 0;
}
void Start()
{
anim = GetComponent<Animator> ();
collected = false;
}
void Update () {
//smooth score animation
m_smoothScore = $$anonymous$$athf.SmoothDamp(m_smoothScore,(float)score,ref m_smoothScoreVelocity, 0.2f, $$anonymous$$athf.Infinity, Time.deltaTime);
//display the text
int toDisplay = (int)$$anonymous$$athf.Round(m_smoothScore);
if (toDisplay != m_displayedScore)
{
m_displayedScore = toDisplay;
text.text = "Score: " + m_smoothScore;
}
//text.text = score + " PTS";
if (score > 0)
{
anim.SetBool ("Points", true);
}
if (collected == true) {
t = Time.time;
text.fontSize = $$anonymous$$athf.Lerp ($$anonymous$$, max, t);
collected = false;
} else {
t = Time.time;
text.fontSize = $$anonymous$$athf.Lerp (max, $$anonymous$$, t);
}
}
}
Answer by PersianKiller · Feb 09, 2018 at 08:03 AM
it's my coins script,take a look at it .(I attached a circle collider2D to the coin)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class coin : MonoBehaviour {
public scoreManager sm;
public int counter;
// Use this for initialization
void Start () {
sm = FindObjectOfType<scoreManager> ();
}
void Update(){
sm.coins += 20;
sm.SetCoinsValue ();
counter++;
if(counter>24){
Destroy (gameObject);
}
}
void OnTriggerEnter2D(Collider2D other){
if(other.CompareTag("Player") ){
GetComponent<SpriteRenderer> ().enabled=false;
GetComponent<CircleCollider2D> ().enabled=false;
enabled = true; // this will active the script.so the script should be disable and when the player collide with the coin ,the player will enable the script.because OnTriggerEnter2D works even if the script is not enable.
}
}
}
and it's my scoreManager .
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class scoreManager : MonoBehaviour {
public int coins;
public Text t1;
// Use this for initialization
public void SetCoinsValue(){
t1.text = coins.ToString ();
}
}
I used update method to add scores.but you should remember disable the script of coins.so if you collide with coins then script will be enabled.
it will add 500 scores,from 1 to 500 !!!! it wasn't what you wanted !!!!!
Answer by MUG806 · Feb 09, 2018 at 09:35 AM
A simple way would be to hold true score in a variable but also have a "displayed score" in another variable. Then in update test if displayed score is less than true score, if so, add 1 and do the opposite if it's too high.
This will work but because updates take variable time it may be seem jittery, and you need to look into the more advanced suggestions in pangaminis response if that bothers you. Alternatively you can put it in fixed update.
Well, I think it's not so advanced, only that it uses float and deltaTime for smoothed value, not int
Yeah, I agree, but they were struggling with your suggestion so I posted a simplified version.
Your answer
Follow this Question
Related Questions
Make my mathf to Wait? :) 2 Answers
Double Score Problem ? 1 Answer
Whole number Mathf.SmoothDamp ? 1 Answer
Points-Counter Problem 2 Answers