Preformatted score text

I’ve gone ahead and used some of the string tools in C# to pre-format my score text, so that it always displays the same number of digits.

I started off with a string of 6 0s, and every time a hit is registered, it removes the appropriate number of characters from the end of the string and puts the score at the end.
Working with strings is always a pain in the butt, but I’m glad I got it working :slight_smile:

    TMP_Text scoreText;
    int score;
    [SerializeField] string scoreBuffer = "000000";
    int cutAmount;

    private void Start(){
        scoreText = GetComponent<TMP_Text>();
    }

    public void IncreaseScore(int amountToIncrease){
        score += amountToIncrease;
        scoreText.text = cutAndClampScore(score.ToString());
    }
    string cutAndClampScore(string scoreString){ //making sure that the score buffer never has less than zero characters.
        if (scoreString.Length > scoreBuffer.Length) {
            cutAmount = scoreBuffer.Length;
        } else {
            cutAmount = scoreString.Length;
        }
        return scoreBuffer.Remove(1,cutAmount) + scoreString;
    }

I do have a question, though. When I was working on it, I originally wanted to initialize the “cutAmount” variable inside the if statements within cutAndClampScore(). However, Visual Studio told me that cutAmount does not exist in the current context. Why does it not allow you to do that?
For reference, this is what that method looked like before I changed it to initialize on the class level.

    string cutAndClampScore(string scoreString){ //making sure that the score buffer never has less than zero characters.
        if (scoreString.Length > scoreBuffer.Length) {
            int cutAmount = scoreBuffer.Length;
        } else {
            int cutAmount = scoreString.Length;
        }
        return scoreBuffer.Remove(1,cutAmount) + scoreString;
    }
1 Like

I think this question is in the wrong subject (Blender3D).

1 Like

Hi WeebleWooble,

It’s great to see that you are challenging yourself. :slight_smile:

Regarding your question about the “non-existent” cutAmount, there is something called scope. Classes, methods, if-blocks and so on form code blocks and a scope. If you declare a variable inside such a code-block, the variable cannot be seen in other code-blocks unless the code-block with the declaration is within the other code block.

You could have solved the problem by declaring the variable at the “top-level” of the method:

Code with local `cutAmount`
string cutAndClampScore(string scoreString){ //making sure that the score buffer never has less than zero characters.
    int cutAmount = 0;

    if (scoreString.Length > scoreBuffer.Length) {
        cutAmount = scoreBuffer.Length;
    } else {
        cutAmount = scoreString.Length;
    }

    return scoreBuffer.Remove(1,cutAmount) + scoreString;
}
Refactored code
string cutAndClampScore(string scoreString){ //making sure that the score buffer never has less than zero characters.
    int cutAmount = scoreString.Length;

    if (scoreString.Length > scoreBuffer.Length) {
        cutAmount = scoreBuffer.Length;
    }

    return scoreBuffer.Remove(1,cutAmount) + scoreString;
}

Done. :slight_smile:


Just a little information in case you did not know that: C# has got a built-in feature that automatically adds leading 0s.


See also:

Thanks, Nina!

I had no idea about that C# feature. Thanks!

I do have a followup question about this line here. Why do you have “cutAmount = cutAmount = …”? Is that a structure for setting two variables equal to be the same thing or am I missing something?

Well spotted. That was a mistake I did while copying and pasting your code around.

I meant: int cutAmount = scoreString.Length;

I edited my previous post accordingly.

Like Nina said, it’s good that you are challenging yourself. There are much simpler ways to do this, though.

One way that uses something similar to what you are doing is

int score = 12;
string scoreString = $"000000{score}"[^6..]; // becomes 000012

which uses some of the new C# goodness. It creates a string that’s padded with more than enough 0’s and adds the score to the end of that. If score is 0 it will be 0000000, if score is 10 it will be 00000010, and if score is 123 it will be 000000123. It then takes only the last 6 characters of that string: 000000, 000010 and 000123 respectively.

The simplest way is to just use C#'s format specifier (Nina linked this)

int score = 12;
string scoreString = $"{score:000000}"; // becomes 000012

However, none of these give you the freedom to specify how big your 0-pad must be

The problem here is the fancy new range stuff. One way to get around that would be to not use it

int score = 12;
string scoreString = $"000000{score}";
scoreString = scoreString.Substring(scoreString.Length - 6); // becomes 000012

This does the same thing as the first example: Creates a long string, and then only use the last 6 characters, but here you can specify how long you want it and what to pad it with

int score = 12;
string padBuffer = "---------"; // make it 9 -'s
string scoreString = $"{padBuffer}{score}";
scoreString = scoreString.Substring(scoreString.Length - padBuffer.Length); // becomes -------12

Another way would be to use the ToString method (uses the format specifiers that Nina linked)

int score = 12;
string scoreString = score.ToString("000000"); // becomes 000012

of course, you could still use it the way you had it, too

[SerializeField] string scoreBuffer = "0000"; // must be valid format specifier
int score = 12;
string scoreString = score.ToString(scoreBuffer);  // becomes 0012

These are just a whole bunch of other ways you could have done it. Well done for trying it on your own, though!

There really are a ton of ways to do it! I may try some of them someday when regular expressions don’t hurt my brain so much.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms