Search code examples
c#unity-game-enginestaticstatic-variables

Statics varibales dont show in Unity


Ok, first, excuse my english. Well, I stay making a SAVEFILE with [Serializable()], there's not the problem, the problem is, when I try to make a change of a this static string with the Username, I can't find the reference to this variable in the other script with de InputField. Nothing strange, the SAVEFILE script just say:

and the script save:

 public static UIsettings uisettings;

    //Data to save.
    public string AirlineName = "Unknow";
    public string UserName = "Unknow";
    //Autoload.
    public bool StartupLoad;

    void Awake()
    {
        if(uisettings == null)
        {
            uisettings = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
        
    }
    void Start()
    {
        if (StartupLoad)
        {
            Load();
        }
    }
    //Guardar
    public void Save() //Start the SAVEGAME code

later, I change the value of Airline Name and Username from other two scripts in InputFields, the two methods look like these:

 public void SubmitName(string newAirlineName)
    {
        if(newAirlineName == "")
        {
            print("Write a valid name");
        }
        else
        {
            print(newAirlineName + " es valido.");
            profileData.AirlineName = newAirlineName;
            profileData.Save();
            Debug.Log(UIsettings.uisettings.AirlineName);
        }
    }

If I call it like this, work, but is useless bacause when I change of scene these values go again to Default, so I use static in the values like:

{
public static string AirlineName = "Unknow";
}

without keys, obiously. But, when I make this the metod of the second script can't show the assigned variable, say: error CS0176: Member 'UIsettings.AirlineName' cannot be accessed with an instance reference; qualify it with a type name instead...

I have a few days trying to solve this by myself but, I dunno what to do.

Is to know that the SAVEGAME script is a DontDestoyOnLoad file, like can be see in the first script, but I this that this is't 'cause the script works fine without the static.


Solution

  • When you have a static variable (public static string AirlineName) you can only reference it using the class name -- not an instance of the class - because only one AirlineName exists, and it is not related to any instance of your class.

    Here's an example of why you're getting your error:

    // This example shows why are you getting the error.  Skip to the second example
    // to see the solution that you should use
    
    public class UiSettings : MonoBehaviour
    {
       public static string AirlineName = "Unknow";
    }
    
    // ...
    
    public void SubmitName(string newAirlineName)
    {
       // Just an example of getting the current instance of UiSettings
       UiSettings profileData = (UiSettings)GameObject.FindObjectOfType(typeof(UiSettings));
    
       // You can't do this because AirlineName is a static property, so you can't use an
       // instance variable (profileData) to access it because AirlineName doesn't belong
       // to an instance     
       profileData.AirlineName = newAirlineName;
    
       // You would have to access it like this
       UiSettings.AirlineName = newAirlineName;
    }
    

    But since you're making UiSettings a singleton class by using DontDestroyOnLoad, you would do this

    public class UiSettings : MonoBehaviour
    {
       public static UIsettings uisettings;
    
       // Do not make these static
       public string AirlineName = "Unknow";
       public string UserName = "Unknow";
    
        void Awake()
        {
            if(uisettings == null)
            {
                uisettings = this;
                DontDestroyOnLoad(gameObject);
            }
            else
            {
                Destroy(gameObject);
            }        
        }
    }
    
    // ...
    
    public void SubmitName(string newAirlineName)
    {
       // uisettings contains an instance of UiSettings, so you are allowed to say
       // UiSettings.uisettings.AirlineName = ...
       UiSettings.uisettings.AirlineName = newAirlineName;
    }
    

    I would also recommend changing the name uisettings to Instance to make it clear that the property references the singleton instance of the class. Like this:

    public class UiSettings : MonoBehaviour
    {
        // Instead of public static UiSettings uisettings
        public static UiSettings Instance { get; private set; }
    }