About 'Reset Game Session'!

In this video (objectives)…

  1. Reinforce the public method paradigm we've been using.
  2. Fix the issue with our score persisting from game session to game session.
  3. How to rename a class.

After watching (learning outcomes)… How to elegantly reset our game session so that our score resets.

(Unique Video Reference: 27_BR_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

Hi, when I’m trying to call the ResetGame method from SceneLoader.cs, I’m getting the red squigglies. I’m not sure what I’ve done wrong.

Capture

When I tried the challenge initially, here is what I wrote. I just tried to make it similar to how it was structured in Level.cs. Regarding this, when is it appropriate to use ‘cached references’ and FindObjectOfType in the way we did in Level.cs?

(Note: I havent renamed GameStatus yet)

Red squigglies might be because you’re missing parentheses after your method - ResetGame()

2 Likes

Oh my god, I feel like an idiot.

2 Likes

Its all part of being a programmer. :slight_smile:

2 Likes

To piggy back off of Sean_Clark’s excellent question. When are Cached references appropriate? I also completed the challenge by referencing Level.cs and Block.cs

Here is what I coded. I named my method within GameStatus.cs LevelReset()

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{

    //Cached reference
    GameStatus levelReset;

    public void LoadNextScene()
    {
        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
        SceneManager.LoadScene(currentSceneIndex + 1);
    }

    public void LoadStartScene()
    {
        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
        SceneManager.LoadScene(0);
        FindObjectOfType<GameStatus>();
        levelReset.LevelReset();
    }

    public void QuitGame()
    {
        Application.Quit();
    }
}

This solution worked! But clearly I have 2 lines of extra code that are unnecessary.

So my question is, why did we use a cached reference for Level.cs but did not use a cached reference for this challenge?

Really enjoying the course so far!

Hi Vincent,

Typically you’d add a member variable when you want to use the data it holds multiple times and/or across multiple methods.

Looking at the code you have posted for the SceneLoader.cs there is absolutely no reason to have it as a member variable at all as the only place you use it is within the one method, LoadStartScene.

On that note, the line of code you have within that method;

FindObjectOfType<GameStatus>();

currently isn’t doing anything, well, it is, but nothing helpful. It will perform the “find” but doesn’t do anything with what it returns. Equally, the levelReset.LevelReset line of code will generate an error if it executes because levelReset has not been instantiated/initialised.

I suspect the reason you don’t see this happen is because before those two lines of code you use SceneManager.LoadScene(0) which loads the other scene before these lines of code have chance to execute.

As a final suggestion, it’s often better to name your variables based on what they are, so for example, you member variable;

GameSession levelReset;

It isn’t really a “level reset”, this is just one of the behaviours that class may provide. It may be better named as;

GameSesson gameSession;

In the above, it is a GameSession. Then, when you call your LevelReset method, your code would read like this;

GameSession.LevelReset();

which perhaps provides the reader with a clearer idea of what it is and what its doing than;

levelReset.LevelReset();

The above would be behaviour.behaviour as opposed to thing.behaviour in the previous example.

Hope the above is of some help :slight_smile:

1 Like

Thanks Rob, as always, great answer.

1 Like

Thanks for the answer Rob!

1 Like

You’re very welcome Vincent :slight_smile:

I tackled this before watching the video (because I didn’t know it was the next video :joy:) and did mine a little differently, simply resetting the score back to 0. The idea was that I’d come back and create a “highScore” int variable, run a check to see if currentScore > highScore before resetting, updating highScore if necessary, then finally displaying the updated highScore on the Start screen.

I’m not sure if this section gets into recording high scores or not, but if anyone else is thinking about tracking them at this juncture, this is how I plan to go about it.

And thats how you know you are a programmer…lol

I did it in a similar fashion, also thinking about later adding a high score feature. No need to delete the original GameStatus class, which is high cost in CPU time (relatively speaking), versus simply resetting the score to 0 and updating the displayed value.

If there is a reason why destroying the GameStatus (or GameSession, as you changed it to be called) is better, I would like to know what that reason is.

I also created a DisplayScore() method inside GameStatus.cs, because there were multiple places that needed to update what was being displayed. So in SceneLoader.cs you have this (as you will see, I comment more than most):
/***
* LoadStartScene will load the first scene in the Build Settings.
***/
public void LoadStartScene()
{
GameStatus gameStatus = FindObjectOfType();
gameStatus.ResetScore();
SceneManager.LoadScene(0);
} // LoadStartScene()

In GameStatus.cs you have this (just showing methods that update the score):
/***
* DisplayScore() displays currentScore on the current game screen.
***/
public void DisplayScore()
{
score.text = “Score:\n” + currentScore.ToString();
} // DisplayScore()

/***
   *       Start is used to cache the Level object.
   ***/
void Start()
{
	currentLevel = FindObjectOfType<Level>();
	DisplayScore();
}   // Start()

/***
*       AddToScore() adds to the currentScore the points for the block that was destroyed.
*       Note:  Later we may want to pass a value based on the type of block that was destroyed.
***/
public void AddToScore()
{
	currentScore += pointsPerBlockDestroyed;
	DisplayScore();
}   // AddToScore()

/***
*       ResetScore() resets the currentScore to 0 for the start of the game.
***/
public void ResetScore()
{
	currentScore = 0;
	DisplayScore();
}	// ResetScore()

I used the following code which worked on first attempt. I admit did not check thoroughly for any bugs might pop up in the future :slight_smile:

public void LoadNextScene()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    SceneManager.LoadScene(currentSceneIndex + 1);

    if ( (currentSceneIndex == 0) && FindObjectsOfType<GameStatus>() != null)
    {
        Destroy(FindObjectOfType<GameStatus>().gameObject);
    }
}

Privacy & Terms