- Home /
Data Persistence Project issues
Hello all!
I've reached a point in which I can't dig out of and hoping to have some other eyes on it. The project is to manage scene flow and implement data persistence between scenes as well as between sessions. I feel like I have the scene flow down as each button I've implemented sends the player to the correct scene with the exception of my pause menu (I need to figure out how to resume play when hitting the resume button, but that's another journey).
I need to figure out 1. How to reset the score when game over happens. It stays and adds to each time a new game is started. And 2. How to implement a "High Score" with an entry field for the players name at the end of the high score winning game.
I have three main scripts MainManager.cs (given to us, but I've made adjustments), ScoreManager.cs, and ButtonManager.cs.
public class MainManager : MonoBehaviour
{
public Brick BrickPrefab;
public int LineCount = 6;
public Rigidbody Ball;
public Text ScoreText;
public GameObject GameOverText;
private static int m_Points;
private bool m_Started = false;
private bool m_GameOver = false;
public GameObject pauseText;
public bool isPauseActive = false;
void Start()
{
isPauseActive = false;
const float step = 0.6f;
int perLine = Mathf.FloorToInt(4.0f / step);
int[] pointCountArray = new [] {1,1,2,2,5,5};
for (int i = 0; i < LineCount; ++i)
{
for (int x = 0; x < perLine; ++x)
{
Vector3 position = new Vector3(-1.5f + step * x, 2.5f + i * 0.3f, 0);
var brick = Instantiate(BrickPrefab, position, Quaternion.identity);
brick.PointValue = pointCountArray[i];
brick.onDestroyed.AddListener(AddPoint);
}
}
}
private void Update()
{
if (!m_Started)
{
if (Input.GetKeyDown(KeyCode.Space))
{
m_Started = true;
float randomDirection = Random.Range(-1.0f, 1.0f);
Vector3 forceDir = new Vector3(randomDirection, 1, 0);
forceDir.Normalize();
Ball.transform.SetParent(null);
Ball.AddForce(forceDir * 2.0f, ForceMode.VelocityChange);
}
}
else if (m_GameOver)
{
if (Input.GetKeyDown(KeyCode.Space))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
if (m_Started)
{
if (Input.GetKeyDown(KeyCode.Escape))
{
PauseGame();
}
}
}
void AddPoint(int point)
{
m_Points += point;
ScoreText.text = $"Score : {m_Points}";
ScoreManager.scoreManager.score = m_Points;
}
public void GameOver()
{
m_GameOver = true;
GameOverText.SetActive(true);
}
void PauseGame()
{
isPauseActive = true;
Time.timeScale = 0;
pauseText.SetActive(true);
}
}
public class ScoreManager : MonoBehaviour
{
public static ScoreManager scoreManager;
public int score;
public int highScore;
void Awake()
{
if (scoreManager != null)
{
Destroy(gameObject);
return;
}
scoreManager = this;
DontDestroyOnLoad(gameObject);
}
}
public class ButtonManager : MonoBehaviour
{
public void MainMenu()
{
SceneManager.LoadScene(0);
}
public void HighScores()
{
SceneManager.LoadScene(3);
}
public void StartNew()
{
SceneManager.LoadScene(1);
}
public void ResumeGame()
{
//need to resume play with saved information from before hitting pause (esc)
}
public void Exit()
{
if UNITY_EDITOR
EditorApplication.ExitPlaymode();
else
Application.Quit(); //original code to quit Unity player
endif
} }
Thank you in advance for taking the time to read and assist!
Not actual solution but Just general pointers to solve your issue(s):
You have really reached a point where it is hard to continue with your current architecture :)
If you need any kind of game play persistent data across scenes then learn to use Scriptable objects. This solves pretty much all the runtime data persistence problems. It also gives a solution how to reset the data to the original values easily. https://docs.unity3d.com/Manual/class-ScriptableObject.html. https://learn.unity.com/tutorial/introduction-to-scriptable-objects
After that you can get familiar with how to load / save game states to / from a disk (or other persistent storage) to accomplish game play data persistence across game play session.
Thank you for this. I'll watch this live session and see what I can learn. Also, the docs link didn't work, but I'm sure I can find it with a quick search. Thanks again!
Answer by StephenWebb · Dec 07, 2021 at 06:07 PM
You're going to need to make use of ScriptibleObject to hold your session persistent data (unless you want to use JSON which is very easy to implement and it's all text, it's human readable and you won't need to convert the ScriptibleObject Asset to a bundled asset at runtime).
Personally I use ScriptibleObject because it's way faster to access complex data - JSON is just easier to deal with and it's very simple to implement. It's slow and it's not very secure - it you only need to have player data for scores and don't care about security, use JSON. If you need to work with complex data that must be secure, use ScriptibleObject.
Accessing ScriptibleObject assets at runtime in a built project won't work well, if at all - ScriptibleObject assets need to be bundled up which is an extra layer of complexity.
You should probably also look into the MVC C# design pattern. I use it along with a few others religiously. It makes working with persistent data a snap.
Wonderful. Second response I've gotten about ScriptableObject and I've got a live session queued up and ready to roll. I've also seen a little about JSON, but had no idea what it was. One of the previous lessons briefly went over it. Thank you Stephen!
Hey TwitchyOrphan, I'm gonna make a couple videos that will show you how to create a system for persistent data. I might even make both JSON and the ScriptibleObject versions.
The videos will demonstrate the creation of EditorWindows for the creation of persistent game card data (the Game is called Castle Cards - its a collectible trading card game inspired by WotC Magic the Gathering computer game released in the late 1990's)
I will try to upload the videos on twitch one every so many days - I already have a TON of rough uncut videos at twitch.tv/stephenwebb1980 so if you want to stop by and follow, that'd be swell lol.
Your answer
Follow this Question
Related Questions
check SQLite database record 1 Answer
When writing a txt file, it says sharing violation 3 Answers
Autosaving 0 Answers
Save Datasets at runtime 2 Answers
Initialize List in User Data Class without deleting binary file 0 Answers