Coding score system

Hi,
I don’t know what I’m doing wrong - possibly a lot - but I’m trying to write a simple score system for the little game I’m doing in the online course ‘Create with Code’. For that I’m actually using the system presented there in the chapter 5 (Lesson 5.2 - Keeping Score - Unity Learn), but as my game is a bit different - a very simple sidescroller - I tried to implement these things into my system but something is wrong. First, I do not get the score to update and second, I just broke the game. I wrote and rewrote it last night for hours and hours and I know it’s messy, but I can’t find a way out. Help would really be appreciated.
P.

using TMPro;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
    public TextMeshProUGUI gameOverText;
    public float verticalInput;
    public float speed = 10.0f;
    public ParticleSystem EnergyExplosion;
    public ParticleSystem DustExplosion;
    public bool gameOver = false;
    private AudioSource playerAudio;
    public AudioClip moneySound;
    public AudioClip explodeSound;
    public ParticleSystem explosionParticle;
    private SpawnManager SpawnManager;
    public int pointValue;
    void Start()
    {
        SpawnManager = GameObject.Find("SpawnManager").GetComponent<SpawnManager>();
        playerAudio = GetComponent<AudioSource>();
    }
    void Update()
    {
       verticalInput = Input.GetAxis("Vertical");
       transform.Translate(Vector3.up * verticalInput * Time.deltaTime * speed);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.layer == 9)
        {
            playerAudio.PlayOneShot(explodeSound, 1.0f);
            gameOver = true;
            Destroy(gameObject);
            Instantiate(explosionParticle, transform.position, explosionParticle.transform.rotation);
            gameOverText.gameObject.SetActive(true);
        }
        else if (other.gameObject.layer == 8)
        {
            EnergyExplosion.Play();
            playerAudio.PlayOneShot(moneySound, 1.0f);
            Destroy(other.gameObject);
            SpawnManager.UpdateScore(pointValue);
        }
    }
}

===================================================

using UnityEngine;
using TMPro;
public class SpawnManager : MonoBehaviour
{
    public TextMeshProUGUI scoreText;
    private int score;
    public GameObject[] enemyPrefabs;
    private float spawnRangeY = 10;
    private float spawnPosZ = -5;
    private float startDelay = 1;
    private float spawnInterval = 0.5f;
    private PlayerController PlayerController;
    void Start()
    {
        InvokeRepeating("SpawnRandomEnemy", startDelay, spawnInterval);
        PlayerController = GameObject.Find("Player").GetComponent<PlayerController>();
        score = 0;
        UpdateScore(0);
    }
    void SpawnRandomEnemy()
    {
        int enemyIndex = Random.Range(0, enemyPrefabs.Length);
        Vector3 spawnPos = new Vector3(-8, Random.Range(-spawnRangeY, spawnRangeY), spawnPosZ);
        if (PlayerController.gameOver == false)
        {
            Instantiate(enemyPrefabs[enemyIndex], spawnPos, enemyPrefabs[enemyIndex].transform.rotation);
        }
    }
    public void UpdaScore (int scoreToAdd)
    {
        score += scoreToAdd;
        scoreText.text = "Score: " + score; 
    }
}
  1. Please use code tags.Otherwise its very difficult to read your code and therefore less people will take the time to read and respond to it.

  2. Add Debug.Log to your code to check what is actually going on and to find out if functions get called at all.
    Like

public void UpdaScore (int scoreToAdd)
{

Debug.Log("UpdateScore: " + scoreToAdd);
score += scoreToAdd;
scoreText.text = "Score: " + score;
}
  1. What do you mean by “I broke the game?”
2 Likes

[QUOTE
3. What do you mean by “I broke the game?”[/QUOTE]
I mean, it won’t start with scripts like these.

I have no idea what’s going on now. After adding the Debug.Log I get this message:
“All compiler errors have to be fixed before you can enter playmode!
UnityEditor.SceneView:ShowCompileErrorNotification() (at C:/buildslave/unity/build/Editor/Mono/SceneView/SceneView.cs:2935)”

If you have compiler errors it wont start at all and you need to fix the error.
Usually the error contains the information about where in your scripts the error occured.
You can then double-click on that error and it will open the corresponding script at the right position.

1 Like

Yep, it’s this ‘Updatescore’. I don’t know what to do with it, where would it’s right place be.

You need to be more specific :slight_smile:

Because of the function “Updatscore” you can’t start the game and Unity complaints about errors?

Or the game works but youe score does not Update?
If the game works: Did you add a debug log message to the UpdateScore function?
If so, does it output something to the console when you start the game?

1 Like

Nope, the game does not work. The debug log said " All compiler errors have to be fixed before you can enter playmode!
UnityEditor.SceneView:ShowCompileErrorNotification() (at C:/buildslave/unity/build/Editor/Mono/SceneView/SceneView.cs:2935)".

Please read the details of the error message.
I guess there are more lines than the ones you post and one of those lines tells you where exactly in your scripts there is an error.

I don’t know. I’m just so absolutely frustrated by now… I just noticed the particle system isn’t working and then I tried to add start and end and replay screens and it messed everything up… It’s just bloody overwhelming…

Hey, Peet. I get your frustration. It’s counterproductive to the programming process, though, so we need to get past it and put our work boots on. Once you’ve taken a bit of time to clear your head and get the stress out, come back and read the rest of this message.

= = = = = = = =

Better? Good. Okay, so let’s talk about code and compilers.

Writing code can be frustrating because sometimes you want to do something very specific, but you don’t know exactly how to do that with the current set of knowledge you have. The nice thing about that is that the exact opposite holds true as well: code only ever does what you tell it to! It never “doesn’t work.” It generally does what it’s supposed to, and it’s how you’re using it that needs to change.

In this case, the issue is that your code is syntactically incorrect. It just means you’re using a word wrong or have your sentence jumbled up. If I say “The quiuck fox brown jumped over lazy dog,” you probably have a good idea of what I’m trying to say, but you’d be able to recognize that my sentence has errors that need to be fixed, like spelling errors, missing words, or words in the wrong order. Your brain is expecting to see one thing, but your eyes are seeing another. How you explain the points that make my sentence incorrect is similar to the process the compiler goes through when reading your code to turn it into something it knows how to work with.

The error you’re mentioning looks like it’s part of Unity’s built-in processes, judging by the path to the file listed in the error message. It’s telling you there’s an error happening on line 2935 of the file SceneView.cs. Well, I don’t know what that file is and I assume it isn’t something you wrote, so let’s ignore it for now. In your Console panel, click the Clear button. Does that remove everything from the error list, so there’s no red messages left anymore? If so, that means there’s no problem with your code, which is great! If there are errors still showing even after you’ve clicked Clear, that means something you wrote needs to be fixed, and we need to know what that message is in full – both the single line that shows in the bar at the bottom of the Editor, and the full message details that only show if you have the Console expanded, like this:

If your error messages did go away, then there’s likely something wrong with your Unity install. You might just need to be running the Editor as an Administrator, if you’re using an account that doesn’t have full privileges on your machine. You might have to reinstall the version of the editor you’re using (you installed it through the Unity Hub, right? Reinstalling is a snap, so don’t sweat it).

Above all else, stay calm and don’t let it break you. Explain issues to us here as if we know nothing about your specific situation or programming in general. This’ll help you mentally focus in on where the problem is coming from, so at the very least you’ll have a better idea of what the problem is, even if you don’t know how to fix it.

4 Likes

To make sure that your unity install is not the problem you could create a new empty project and check if you can press play without any error messages.

1 Like

Thank You! I needed that. :slight_smile:
Well, I now just rolled back the game as I see how the problems just pile up. At the moment I have a simple game where Player has to dodge flying enemies and catch flying chalices which give score. What I have so far is the flying and dodging and catching part - all works just fine. But I want to add:

  • score system;
  • explosions;
  • title screens.
    As I said, I rolled my thing back a bit because I noticed how I am unable to tackle all these problems together. So, I’ll paste here the code of the two scripts which basically make my game run. At the moment it won’t run because there is a problem with the ‘Game Over’ text, to be more precise, the line gameOverText.gameObject.SetActive(false);. Why? Well, I think I have messed up big time. Namely - I tried to facilitate all the important operations (spawning of enemies, Player control, particle system and so on) in just two scripts. Could it be, it’s not meant to function like that? That that’s where the problems start? I don’t know, I’m just too much of a beginner here…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PlayerController : MonoBehaviour
{
    public TextMeshProUGUI gameOverText;
    public float horizontalInput;
    public float verticalInput;
    public float speed = 10.0f;
    public ParticleSystem EnergyExplosion;
    public ParticleSystem explosionParticle;
    public bool gameOver = false;
    private AudioSource playerAudio;
    public AudioClip moneySound;
    public AudioClip explodeSound;
   
    // Start is called before the first frame update
    void Start()
    {
        playerAudio = GetComponent<AudioSource>();
        gameOverText.gameObject.SetActive(false);
    }
    // Update is called once per frame
    void Update()
    {
        verticalInput = Input.GetAxis("Vertical");
        horizontalInput = Input.GetAxis("Horizontal");
        transform.Translate(Vector3.up * verticalInput * Time.deltaTime * speed);
        transform.Translate(Vector3.right * horizontalInput * Time.deltaTime * speed);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.layer == 9)
        {
            Debug.Log("GAME OVER!");
            playerAudio.PlayOneShot(explodeSound, 1.0f);
            gameOver = true;
            Destroy(gameObject);
            explosionParticle.Play();
            gameOverText.gameObject.SetActive(true);
        }
        else if (other.gameObject.layer == 8)
        {
            EnergyExplosion.Play();
            playerAudio.PlayOneShot(moneySound, 1.0f);
            Destroy(other.gameObject);
        }
    }
}
 using UnityEngine;
public class SpawnManager : MonoBehaviour
{
    public GameObject[] enemyPrefabs;
    private float spawnRangeY = 10;
    private float spawnPosZ = -5;
    private float startDelay = 1;
    private float spawnInterval = 0.5f;
    private PlayerController PlayerController;
    void Start()
    {
        InvokeRepeating("SpawnRandomEnemy", startDelay, spawnInterval);
        PlayerController = GameObject.Find("Player").GetComponent<PlayerController>();
    }
    void SpawnRandomEnemy()
    {
        int enemyIndex = Random.Range(0, enemyPrefabs.Length);
        Vector3 spawnPos = new Vector3(-8, Random.Range(-spawnRangeY, spawnRangeY), spawnPosZ);
        if (PlayerController.gameOver == false)
        {
            Instantiate(enemyPrefabs[enemyIndex], spawnPos, enemyPrefabs[enemyIndex].transform.rotation);
        }
    }
}

Your script lengths aren’t the problem. I’m currently working with scripts that are over 1000 lines, and while it’s not considered “good practice,” it certainly works.

It’s not that helpful for you to tell us the game “doesn’t run.” You have to give us that error message, in full, and the full script that the error message is pointing to. So if your compiler is saying there’s an error on line 42 of PlayerController.cs, copy the full error message here so we can see what’s going on.

I imagine it’s a NullReferenceException, since that’s one of the most common ones people run into, and it fits with what you’re doing on that line. I’m just gonna move forward assuming that’s what you’re running into, but please correct me if I’m wrong.

A null reference is when you try to do something with an object, but that object isn’t found. Imagine I give you a set of instructions:

  • I will hand you a paper bag.
  • Open that bag and inside you should see a jar.
  • Open that jar and use your finger to eat the strawberry jam inside it.

You understand perfectly what to do because my instructions are clear and logically make sense. But then I hand you the bag, and you open it to find there’s no jar inside. Your response to step 2 might be “Uh, there is no jar.” and when you get to step 3 you’d say “Hey, I can’t open the jar because it doesn’t exist!”

That’s what a null reference is. You’re telling the compiler to look at the gameOverText variable (which it knows is a TextMeshProUGUI type) and get the gameObject property it has. The compiler knows a TextMeshProUGUI type does have a gameObject property, so that’s not a problem, at least logically. You’re then telling it to set the active state of that GameObject to true using SetActive, which again, is fine as far as the rules go.

What’s probably happening is that you don’t have anything assigned to the gameOverText property in the Inspector. So when you get to line 42, the compiler is saying “Hey, you’re telling me to get the gameObject out of the gameOverText bag, but that bag is empty!”

One way to figure this stuff out is to simply Google the error codes you run into, maybe throwing “Unity” in your search terms just to get things that relate more closely to what you’re doing. Read the top 10 results, which will probably be posts of people having similar issues to you, and see if the answers provided to them help you figure out what’s going on in your situation. I promise you you’re not the only one who’s struggled with this stuff, and the idea of online communities like this is that we help each other so that the people who aren’t posting can find the answers when they’re struggling, too. When you’re starting out, almost any problem you can run into has probably already been asked hundreds of times, and the answers to how to fix them are out there just waiting for you to find them.

2 Likes

Yes, it is the NullReferenceException. What I just don’t understand is something very principal: what object should be set to what object? I have tried one way and another - and believe me, before posting here, I had tried all the possiblities that came in mind and I also googled extensively - but I just do not get it.

NullReferenceException: Object reference not set to an instance of an object
SpawnManager.UpdateScore (System.Int32 scoreToAdd) (at Assets/Scripts/SpawnManager.cs:39)
SpawnManager.Start () (at Assets/Scripts/SpawnManager.cs:21)

The lines in question are those:

 UpdateScore(0);
    public void UpdateScore(int scoreToAdd)
    {
        score += scoreToAdd;
        scoreText.text = "Score: " + score;
    }

I don’t undertand what’s supposed to be connected with what. :frowning:

Damn! I got it! I looked at the problem the wrong way - the NullReferenceException was not trying to tell me that something wasn’t connected but, that something wrong was connected! I just had to remove a connection and now it functions! Sorry for making things messy!:sweat_smile: