Use of static when it is harder to make a gameobject a child of GameStatus

In my code, the highscore is calculated by multiplying the base score by a multiplier that grows with every block destroyed and that resets when the ball touches the paddle or the lose collider. For this I access the class ball from gamestatus and for some reason I am not able to successfully implement the singleton on this, the ball would stop working, or the blocks would stop breaking, or the ball would randomly spawn in the middle of the lvl 2.

Is this use of static variable ok?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class GameStatus : MonoBehaviour
{
    public TextMeshProUGUI scoreText;
    [Range(0.5f,2f)]public float timeSpeed = 1f;
    public static int currentScore = 0;
    public float baseScoreValue = 100;
    Ball ball;

    // Start is called before the first frame update
    void Start()
    {
        ball = FindObjectOfType<Ball>();
        scoreText.text = currentScore.ToString();
    }

    // Update is called once per frame
    void Update()
    {
        Time.timeScale = timeSpeed;
    }

    public void AddToScore()
    {
        currentScore += System.Convert.ToInt32(baseScoreValue * ball.comboMultiplier);
        scoreText.text = currentScore.ToString();

    }
}

Hi,

Generally, a public static variable is considered as very bad practice because everything can access this variable and mess around with the value.

A separate class instance storing the score would be much better because safer:

using System.Collections;
using System.Collections.Generic;

public class Score
{
    private int score = 0;

    // The constructor
    Score() { }

    // The implementation of the actual "lazy" singleton pattern.
    // You can find more information on this on the internet.
    private static Score instance = new Score();

    public static Score Instance
    {
        get
        {
               if (instance == null)  {  instance = new Score(); }
        }
    
       return instance;
    }

    // Pass on the score value
    public int GetScore()
    {
        return score;
    }

    // Add the passed on value to score
    public void AddToScore (int score)
    {
        this.score += score;
    }
}

And in your GameStatus class, you remove the score stuff and do the following:

public class GameStatus : MonoBehaviour
{
   Score score;

   void Start ()
   {
        score =  Score.Instance();
   }

   public void AddToScore (int score)
   {
        int newScore = baseScoreValue * score;

        // Save the score in your Score instance
        score.AddToScore(newScore);

        // Fetch the current total score from your Score instance
        scoreText.text = score.GetScore().ToString();
   }
}

Of course, you could outsource the baseScore to the Score instance/class if you want. The code above is just an example of how you can work with a C# class which is independent from Unity. Then you can realise an actual singleton without having to worry about Unity’s rules.

When your ball(?) calls the AddToScore method of your GameStatus, you pass on the value of your ball. Whatever that might be.

1 Like

Ill try this, thanks!

How are you getting on with this, @S_de_Incognito?


See also:

I tried to use a separate class, kept getting null reference errors and after a couple of hours shelved this issue and left it temporarily as a public variable because that worked and I needed to keep working on the game, have to introduce more persisting variables when I finish the settings menu so then I’ll try again with a separate class for all of them.

Getting into a big C# course that lasts 5 days so I think I will be able to use OOP and classes a bit better then

I’m sure knowing OOP principles will help you solve the problem. :slight_smile:

1 Like

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