Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

static variables questions

Discussion in 'Scripting' started by SmokyZebra, May 2, 2014.

  1. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    Hello, in my game, there is 3 scenes, an intro (1), the main menu(2) and the game in itself(3). My static vars are in a script, let's say StaticVars that is attached to a game object that is in scene 3.

    I know that if i load scene 3 (from the menu, scene 2), reload scene 2 and then reload scene 3 the static vars will keep their value and not reset.

    1. Can i access to those statics var in scene 2 before scene 3 is loaded for the first time? (StaticVars script is not attached to any objects in scene 2)

    2. Can i access to those statics var through StaticVar.aStaticVar in scene 2 even if StaticVars is not present in the scene ? (after have loaded scene 3 once, which is i guess initializating the static vars)

    3. if no, can i put an empty game object with StaticVars in scene 2 ? (There would be 2 scene each containing a game object with StaticVars, will they "merge" ? Or is that impossible to do ?)

    What i need is to be able to change values of the static vars from scene 2 and scene 3. (but i don't need to change their values before scene 3 is loaded for the first time)

    Thanks in advance.
     
  2. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    1. If those static vars are not MonoBehaviours, then yes you should be able to access them before the MonoBehaviour-derived class that contains them is created.

    2. Same as one.

    3. That shouldn't be necessary.

    It's probably best to avoid all this confusion altogether and just put your static variables in a static class that doesn't inherit from MonoBehaviour or any other class for that matter. Then just use that to access all those shared static variables.
     
  3. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    What do you mean by not MonoBehaviour ? I thought that all code written in script inherited from MonoBehaviour. But I've find a workaround i guess : Instead of puting my StaticVars script on an object in scene 3, i'll move it to an object in scene 2 (wich is loaded before) and call DontDestroyOnLoad to make sure i can access it anywhere through StaticVars.aStaticVar.
     
  4. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    That is not the case at all. You don't have to have your classes inherit from MonoBehaviour. You even have to explicitly indicate that a class inherits from MonoBehaviour if you're programming in C#.
     
  5. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    Just like @shaderop said. You could do a game registry like this:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class MyRegistry {
    5.  
    6.     public static string gameState; // menu, playing, end.. etc
    7.     public static int curLevel;
    8.     public static int score;
    9. }
    10.  
    Access to vars:
    MyRegistry.gameState = "menu";
    MyRegistry.score += 10;
    Debug.Log(MyRegistry.curLevel);

    Or you could do a simple game manager for same data with some functionality:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class MyGameManager {
    5.  
    6.     public static string gameState; // menu, playing, end.. etc
    7.     public static int curLevel;
    8.     public static int score;
    9.    
    10.     static MyGameManager(){
    11.       curLevel =0;
    12.       score =0;
    13.     }
    14.  
    15.     public static void NextLevel(){
    16.       curLevel++;
    17.       score += 100;
    18.  
    19.       Debug.Log("level done.. load next");
    20.       Application.LoadLevel(curLevel);
    21.     }
    22. }
    23.  
    And you can also use other static classes inside ..like Debug, Application, Vector3 or whatever (also your own other static classes)

    You can also use DontDestroyOnLoad as you have already tried. Another simple solution is to use PlayerPrefs to save data:
    https://docs.unity3d.com/Documentation/ScriptReference/PlayerPrefs.html

    And off course you can combine for example having game manager to keep track for current level and score, and inside the GameManager use PlayerPrefs to save high score between play sessions. This can be done like this:

    Code (csharp):
    1.  
    2.  public static void SetHighScore(){
    3.   PlayerPrefs.SetInt("hs", score);
    4.   Debug.Log("New HiScor saved: " + score);
    5.     }
    6.  
    7.     public static void GetHighScore(){
    8.   int _highScore = PlayerPrefs.GetInt("hs");
    9.   Debug.Log("HiScor: " + _highScore);
    10.     }
    11.  
     
  6. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    Thanks, if using DontDestroyOnLoad Don't work i'll do as you said. But i can't use PlayersPrefs (well i do but only for a few stuff) because it's really slow and that i have a lot of static vars to manage. My game is a 4x strategy game that is set in the W40k Battlefleet Gothic universe. When i load Scene 3, the game generates at least 100 planets and that can go up to 1000 planets (depending on player selection in scene 2). All that planets have between 100 and 200 variables (stored in static arrays) + I have a lots of other static vars to set the cost and stats of buildings, ships, weapons and so on. If the player go back to the menu and starts a new game, i need the statics var of the planets to be reinitializated (some will in any case, because the game will regenerate new planets that will errase vars in first slots, but some may not be errase that way, for exemple if the first game had 190 planets and the second only 150 : 40 slots won't be errase in that case. to avoid this, i want to reset static arrays in scene 2 if the player start a new game. And i also need vars to be changed if the player load a game (from txt files, not playerprefs) Another thing is that the game generate txt files the first time played with all cost and stats of buildings, weapons, ships etc.. This is to allow the player to make modifications to the game, only changing entries in the text files. But i need those txt files to be loaded by the game to replace static vars (costs, stats...) before the scene 3 is loaded (or at the beginning of scene 3) I now how to create txt files and load them, now i just need Statics vars to be in scne 2, so i'll now try the DontDestroyOnLoad thing and i'll tell you if it worked.
     
  7. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    It seems to work as i want with DontDestroyOnLoad, my SV are initializated in scene 1 and i can acces them with StaticVars.astaticVar in scene 2 and 3.
     
  8. SmokyZebra

    SmokyZebra

    Joined:
    Mar 13, 2014
    Posts:
    139
    Also, i'm scripting in Javascript, and the Unity script reference says "Using Javascript every script automatically derives from MonoBehaviour." So i could not do what you said, but anyway it's working as i need now.