How to have changeable variables that work between multiple scripts and multiple scenes.

I’m trying to make a game that has a currency. I want other scipts to be able to modify/edit the amount, and the variable to be useable on multiple scenes.

I would use public variables, but I don’t know if they work on other scenes, nor do I know if you can change them.

A static field would be the easiest.

Or you can use DontDestroyOnLoad() to let a gameobject survive when the scene changes.

To make my variable last multiple scenes, I think that DontDestroyOnLoad() might work.
However, I still don’t know how to (for static fields)
Acess Them
Change them from another script…

They can be accessed directly, with no need to get access to the script, because they “live” outside gameObjects. Very handy. And they persist through the entire game. They can be in any script, including ones attached to gameObjects, which is a little unintuitive (at least it was for me). You can also make static classes.

In any script, say this one’s called currencyScript:

public static int currencyAmount = 5;

In any other script:

currencyScript.currencyAmount = 10;
print(currencyScript.currencyAmount);

So for the script, do I just make it and NOT put it on an empty gameObject?

For static stuff, YES. This may be all you need.

For DontDestroyOnLoad / Singleton type stuff, the script will get on a GameObject, but not through your direct action.

Here’s the pattern I use for Game Manager-y stuff. There are also plenty of GameManager type tutorials, each one done a slightly-different way:

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

https://pastebin.com/SuvBWCpJ

Unity3D Singleton with Prefab used for predefined data:

https://pastebin.com/cv1vtS6G

These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

public void DestroyThyself()
{
   Destroy(gameObject);
   Instance = null;    // because destroy doesn't happen until end of frame
}

If I make the script with the static currency variable, would it just be accessable (and changeable) in any script, so I don’t need DontDestroyOnLoad() ? Also, I want to use the Start() function to get the money variable from a file (so it doesn’t change).

If the script isn’t attached to anything, can it still do Start() , or is the another way?

If you mark it public: yes. However, I would not go for public variables. If you need to set them, do it through a property.

Start() is only called on classes deriving from MonoBehaviours (and only if they are present in the scene or instantiated during runtime). You can however have a static constructor on a class which is called automatically the first time you access anything of that class.

Here is some example code…

public enum Currency { UsDollars, Euros, Yen, }

public class MyClass
{
    private static Currency currency = Currency.UsDollars;
    public static Currency Currency { get => currency; set => currency = value; }

    private static float money;
    public static float Money => money; // <- lazy property with getter but no setter

    static MyClass() // <- static constructor. called as soon as anything of the class is accessed
    {
        string fileContent = System.IO.File.ReadAllText("systemPath/To/File.txt");
        float.TryParse(fileContent, out money); // <- assuming there is just a number in the file
    }
}

Note: the code above is not tested. Also, you would usually do some error handling to check if the file exists and if the content could be parsed to float.