[英]How can I update my GUI score one point at a time?
If a player receives X amount of points for doing something in my game I want the scoreboard to update showing each number from 0 - X very briefly. 如果一名玩家在我的游戏中获得X分数用于做某事,我希望记分牌能够更新显示0到X中的每个数字。 I'm going for an analog style scoring system like those old clocks where you can watch the numbers change, except the change will happen quickly because hundreds of points can be added at the same time.
我正在寻找一个模拟风格的评分系统,就像那些可以观察数字变化的旧时钟,除了变化很快就会发生,因为可以同时添加数百个点。
Currently, X amount of points are updated instantly when points are awarded: 目前,当获得积分时,X点数会立即更新:
/****************************** Platform Collision ***************************/
void OnCollisionEnter2D(Collision2D coll)
{
foreach(ContactPoint2D contact in coll.contacts)
{
newPlayerHeight = transform.position.y;
// Don't count the first jump
if(newPlayerHeight < 0){
newPlayerHeight = 0;
}
// If the player jumps down, don't reduce points
// Add a tolerance for variable collision positions on same platform
if(newPlayerHeight < oldPlayerHeight + -0.05f){
newPlayerHeight = oldPlayerHeight;
}
// Send the height to the Score class
Score.SP.updateScore(newPlayerHeight);
oldPlayerHeight = newPlayerHeight;
}
}
/******************************* Score class *********************************/
public void updateScore (float newScore)
{
// Display GUI score
score = (int)(newScore * 76);
guiText.text = "Score" + score;
}
I messed around with a for-loop to try and achieve this but got nowhere close. 我用一个for循环搞砸了试图实现这个但是无处接近。
I just created this code, which solves your problem. 我刚刚创建了这个代码,它解决了你的问题。 I am currently using it in my own game.
我目前正在自己的游戏中使用它。
The main idea of the ScoreManager
class is to keep tract of the score and update it every frame. ScoreManager
类的主要思想是保持得分并在每一帧更新它。 It uses a Stack
to keep track of the score to be added, that way we don't have a magic number increasing the score. 它使用
Stack
来跟踪要添加的分数,这样我们就没有增加分数的幻数。
So when the player earns a new point just call the addScore()
function then the ScoreManager
class will handle the updating all by itself. 因此,当玩家获得新点时,只需调用
addScore()
函数,然后ScoreManager
类将自行处理更新。
It will have a thread always running which will increase from currentScore
to newScore
digit by digit, that way the change is observable by users like you wanted. 它会有一个始终运行的线程,它会
newScore
位从currentScore
增加到newScore
,这样就可以像你想要的那样由用户观察到这种变化。
The thread was added to reduce the "lag" you are experiencing in the other question you posted : Why is my game lagging huge when I call a method? 添加了这个主题是为了减少你在发布的另一个问题中遇到的“滞后” : 为什么当我调用方法时我的游戏会滞后?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
public class ScoreManager : MonoBehaviour
{
public GUIText score;
private int currentScore = 0;
public int scoreToUpdate = 0;
private Stack<int> stack;
private Thread t1;
private bool isDone = false;
void Awake()
{
stack = new Stack<int>();
t1 = new Thread(updateScore);
t1.Start();
}
private void updateScore()
{
while(true)
{
if(stack.Count > 0)
{
int newScore = stack.Pop() + currentScore;
for(int i = currentScore; i <= newScore; i++)
{
scoreToUpdate = i;
Thread.Sleep(100); // Change this number if it is too slow.
}
currentScore = scoreToUpdate;
}
if(isDone)
return;
}
}
void Update()
{
score.text = scoreToUpdate + "";
}
public void addScore(int point)
{
stack.Push(point);
}
public void OnApplicationQuit()
{
isDone = true;
t1.Abort();
}
}
I plan to turn this code into a Singleton so that there is only one instance of this class in my game. 我计划将此代码转换为Singleton,以便在我的游戏中只有一个此类的实例。 I highly recommend you do the same.
我强烈建议你这样做。
Have you tried using a Unity coroutine? 你尝试过使用Unity协程吗? It could be easier to implement, starting a coroutine and letting the frame update between each increase in the score would be a simple way to get things going.
它可能更容易实现,启动协程并让分数的每次增加之间的帧更新将是一个简单的方法。
A coroutine allows access to yield return null
this will wait until the end of the current frame to continue with the function. 协程允许访问
yield return null
这将等到当前帧结束以继续该函数。
...
StartCoroutine(AddtoScore(ValuetoAdd));
...
...
public IEnumerator AddtoScore(int value) {
for(int i = 0; i < value; i++) {
currentScore++;
guiText.text = "Score: " + currentScore;
yield return null;
}
}
...
However the downside of this is that if you score again while it is adding points it may create some graphical problems. 然而,这样做的缺点是,如果你在添加点时再次得分,可能会产生一些图形问题。
On the other hand you could place it in the Update function the same style. 另一方面,您可以将它放在更新功能中相同的样式。 Unity calls the Update function once every frame.
Unity每帧调用一次Update函数。
...
void Update(){
if(currentScore < scoreToUpdate) {
currentScore++;
guiText.text = "Score: " + currentScore;
}
}
...
However both of these methods do require that the class they are in inherits from monodevelop: 但是,这两种方法都要求它们所在的类继承自monodevelop:
public class Scoring : MonoBehaviour
Quick and dirty solution, using HOTween (which is free and open source). 快速而肮脏的解决方案,使用HOTween(免费和开源)。 Note that it wont show all numbers, just as many as it can within
transitionTime
seconds. 请注意,它不会显示所有数字,只能在
transitionTime
秒内显示所有数字。
using Holoville.HOTween;
...
int displayScore = 0;
public void updateScore (int newScore)
{
if (oldScore != newScore)
{
float transitionTime = .2f;
HOTween.To(this, transitionTime, "displayScore", newScore);
}
}
public void Update() {
guiText.text = "" + displayScore
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.