Unfortunately Unity does not have a build-in savegame system. So every game needs to develop an own savegame system which is tailored to the architecture and requirements of that specific game. That means there is no "best" way to save data, only the way which is best for you.
When you have very little data to save, then using the PlayerPrefs class can be a quick and easy way to do it. In your particular case, this could be sufficient. But it is intended for, well, preferences. A short list of key-value pairs. It is not designed to hold large amounts of data, and even allowing more than one savegame quickly becomes messy.
So you likely won't get around inventing your own savegame file format which you read and write with the standard C# classes like StreamWriter
/ StreamReader
(for text-based formats) or FileStream
(for binary-based format).
When you only want to save the game state between scene changes, then you only need to persist the data which you already need to handle between scenes. That makes a lot of things a lot easier, because you already have a good overview of what data you have.
But if you want to have a system which allows to save and reload the game at any time, then it gets a lot more complicated. Such a system needs to:
- Find out which gameObjects are currently in the game
- Read any data about them which is worth persisting
- Compile all that data into a file format
- Save that file
- Read that file and parse it
- Recreate all the gameObjects with their components based on the content of the file
- Set their variables according to the content of the file
As you can see from the complexity of some of these points, this is not something where one solution fits every game. But a couple tools that could come in handy for creating your savegame system could be:
- Using the Unity serialization system and see how far it gets you (unfortunately it has some limitations)
- Interfaces which mark a MonoBehaviour as "Saveable" and includes methods which turn that component into a data representation and can set the state of that component from such a data representation. (Unfortunately that won't help you with Unity standard components).
- Behaviours which take care of persisting / restoring all the components on a specific type of gameObject they are on, including Unity-specific components. But that might create quite a lot of maintenance work in the long run.
- Reflection to find out what variables an object has and attempt to persist / restore it automatically
- Attributes to mark variables which should / should not be saved by your reflection-based system