Search Unity

Static variables?

Discussion in 'Scripting' started by Quist, Jul 27, 2015.

  1. Quist

    Quist

    Joined:
    Feb 25, 2014
    Posts:
    284
    I´m using a lot of static variables so i can access the variables from other scripts.
    But i´ve recently found out that when i change the scene the variables doesn´t reset but carry on the information from the last scene...

    Is there a way to prevent the static variables from saving information through scenes?
     
  2. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yep: don't use static values directly. You can keep doing things the same way you've been doing them by setting up a Singleton instead (a single static reference to a class object instance). You set up a Singleton by using something like:
    Code (csharp):
    1. public static ThisClass instance = null;
    2.  
    3. void Start()
    4. {
    5.     if (!instance)
    6.         instance = this;
    7.     else
    8.         Destroy(this);
    9.     }
    10. }
    Or something. There will only be allowed to be one copy of this script in the scene (you can also replace Destroy(this) with Destroy(this.gameObject) to make sure only one copy of the GameObject is allowed in the scene). This way, the destruction of the GameObject will also destroy this script, along with its members and their values, and loading a scene will "refresh" everything.

    Alternatively, you should really get used to passing around and locating GameObjects and using GetComponent to get their various scripts to access the data inside. There are times where Singletons are extremely useful, but if you can easily avoid using one, then it's best to avoid it.
     
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,529
    This is considered bad practice.

    You should not be using static variables just because its convenient to access them from other scripts. Get references to relevant objects and store them in variables, use managers and find ways to reduce the need for script-to-script communication.
     
    blizzy and Quist like this.
  4. Quist

    Quist

    Joined:
    Feb 25, 2014
    Posts:
    284
    Thanks for the great explanation - Im trying to find the script component now instead of using Static variables. But i still get the error:
    An instance of type 'PlayerStat' is required to access non static member 'Dead'.

    Code (JavaScript):
    1. #pragma strict
    2.  
    3. private var player1 : GameObject;
    4. private var playerStat : PlayerStat;
    5. private var player2 : GameObject;
    6. private var playerStat1 : PlayerStat1;
    7.  
    8.  
    9. function Start ()
    10. {
    11.     player1 = GameObject.FindGameObjectWithTag("Player1");
    12.     playerStat = player1.GetComponent(PlayerStat);
    13.     player2 = GameObject.FindGameObjectWithTag("Player2");
    14.     playerStat1 = player2.GetComponent(PlayerStat1);
    15. }
    16.  
    17. function OnTriggerEnter(collision : Collider)
    18. {
    19.    if(collision.gameObject.tag == "Player1")
    20.     {
    21.         PlayerStat.Dead = true;
    22.     }
    23.     if(collision.gameObject.tag == "Player2")
    24.     {
    25.         PlayerStat1.Dead = true;
    26.     }
    27. }
     
  5. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Capitalization problems. You're naming the class and not the instance again. You need to use "playerStat.Dead = true".

    Also, when you're using GetComponent with the class name as a parameter like "GetComponent(SomeClass)" it returns an "object", generically. You'll need to cast it to the correct type yourself by doing "GetComponent(SomeClass) as SomeClass" or "(SomeClass) GetComponent(SomeClass)". Alternatively, you can use "GetComponent<SomeClass>()" and it'll already return as the correct type- you won't need to cast it.
     
  6. Quist

    Quist

    Joined:
    Feb 25, 2014
    Posts:
    284
    I dont really get what you mean, but i´ve fixed the capitalization issue and the problem is now that the variable its trying to access called "Dead" ain´t static.

    How do you get around the static variables?

    Console: An instance of type 'PlayerStat' is required to access non static member 'Dead'.
     
  7. matthewseaward

    matthewseaward

    Joined:
    Apr 12, 2013
    Posts:
    50
    PlayerStat is the name of the class. You've got a capitalization issue - you need to change it so:
    Code (CSharp):
    1.   playerStat.Dead = true;
    You don't want to make 'Dead' a static variable. A static variable is a variable that is shared by all instances of a class - eg...all players share the same value - if you kill player1 you kill everyone.
    You want 'Dead' to be unique to each player therefore make dead 'public' in your class definition - or better yet, create getters/setters.

    Personally, I'd change the names of the playerStats - since I forsee it getting confusing...The stats for player 2 are called 'PlayerStats1':

    Code (CSharp):
    1. #pragma strict
    2. private var player1 : GameObject;
    3. private var player1Stats: PlayerStat;
    4. private var player2 : GameObject;
    5. private var player2Stats : PlayerStat1;
    6. function Start ()
    7. {
    8.     player1 = GameObject.FindGameObjectWithTag("Player1");
    9.     player1Stats = player1.GetComponent<PlayerStat>();
    10.     player2 = GameObject.FindGameObjectWithTag("Player2");
    11.     player2Stats = player2.GetComponent<PlayerStat>();
    12. }
    13. function OnTriggerEnter(collision : Collider)
    14. {
    15.    if(collision.gameObject.tag == "Player1")
    16.     {
    17.         player1Stats.Dead = true;
    18.     }
    19.     if(collision.gameObject.tag == "Player2")
    20.     {
    21.         player2Stats.Dead = true;
    22.     }
    23. }
     
  8. Quist

    Quist

    Joined:
    Feb 25, 2014
    Posts:
    284
    When using the code you wrote i get a lot of errors since it doesnt understand this part: <PlayerStat1>();

    BCE0044: expecting ), found ';'.

    Code (JavaScript):
    1. #pragma strict
    2.  
    3. private var player1 : GameObject;
    4. private var playerStat : PlayerStat;
    5. private var player2 : GameObject;
    6. private var playerStat1 : PlayerStat1;
    7.  
    8.  
    9. function Start ()
    10. {
    11.     player1 = GameObject.FindGameObjectWithTag("Player1");
    12.     playerStat = player1.GetComponent<PlayerStat>();
    13.     player2 = GameObject.FindGameObjectWithTag("Player2");
    14.     playerStat1 = player2.GetComponent<PlayerStat1>();
    15. }
    16.  
    17. function OnTriggerEnter(collision : Collider)
    18. {
    19.    if(collision.gameObject.tag == "Player1")
    20.     {
    21.         playerStat.Dead = true;
    22.     }
    23.     if(collision.gameObject.tag == "Player2")
    24.     {
    25.         playerStat1.Dead = true;
    26.     }
    27. }
     
  9. matthewseaward

    matthewseaward

    Joined:
    Apr 12, 2013
    Posts:
    50
    <PlayerStat1> should be <PlayerStat> (That's the type of class/component you are trying to access)
     
  10. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,336
    In UnityScript, generics has a '.' in front of them. See the Generics page:

    Code (CSharp):
    1. //In C#
    2. var obj = GetComponent<Rigidbody>();
    3. //In JS
    4. var obj = GetComponent.<Rigidbody>();
    So it should actually be player1.GetComponent.<PlayerStat>(); and player2.GetComponent.<PlayerStat>();


    I'd really like to know why that '.' is there. The more I look at UnityScript, the more it seems like the language is an elaborate trolling of the userbase of Unity.
     
  11. Quist

    Quist

    Joined:
    Feb 25, 2014
    Posts:
    284
    Thanks @Baste & @matthewseaward for the great help!
    It´s all working now, i jsut had to put the "." in the script you gave me matthew :)
     
  12. matthewseaward

    matthewseaward

    Joined:
    Apr 12, 2013
    Posts:
    50
    To be completely honest - I didn't even realise this was in UnityScript...so sorry for the C# answer o_O

    Glad it's all working now :)