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

Replacement for my static variables.

Discussion in 'Scripting' started by Elias.W, Jun 16, 2014.

?

Do you use static variables from time to time?

  1. Yes

    100.0%
  2. No

    0 vote(s)
    0.0%
  1. Elias.W

    Elias.W

    Joined:
    Jun 13, 2014
    Posts:
    2
    Hello, I've been trying to access variables in one script from another and after searching I found an answer by declaring the variables I need as static. Though I also found out that the use of static variables is most of the time considered bad. After searching for an answer on why they should be avoided I found out these things:

    1."The problem is that this is intrinsically not OOP because it disregards encapsulation. If a variable can be altered by any instance of a class then the fundamental principle behind encapsulation/information hiding is lost entirely" - http://r.je/static-methods-bad-practice.html
    2. That it's harder to test objects that use static methods because anything outside of the object you're testing can affect it.

    I tried googling to find a replacement for static variables and I "might" have found something relevant, but because I only speak noob I had a hard time following. So I'm posting here hoping to get an easy to understand discussion about static variables and atleast an answer on how to write my code without static.

    //script 1
    public class GravityObject : MonoBehaviour {

    [HideInInspector]
    public Vector3 gravityObject;
    private RaycastHit hit;

    //Use this for initialization
    void Start () {}​

    //Update is called once per frame
    void Update () {
    gravityObject = transform.position;
    Debug.DrawRay(gravityObject,GravityPointScript.gravityPoint - transform.position);​

    }
    }

    //script 2
    public class GravityPointScript : MonoBehaviour {

    public static Vector3 gravityPoint;

    //Use this for initialization
    void Start () {}​

    //Update is called once per frame
    void Update (){
    gravityPoint = transform.position;
    }
    }

    If you create multiple cubes in Unity and add the GravityPointScript script to one of them and the GravityObject script to the rest you will see all lines connecting from the gravity objects to the gravity point. Is it possible to get the same result without the use of static variables? If not, is it really okay to still use them in this scenario?
     
  2. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Yes. By using GetComponent.
    GetComponent allows you to grab a component from a gameObject and access the public information on it. For example:

    GameObject B has a health script with a public variable. It also has some random script. I can access the information (public variables and functions) of that script by using get component like so:

    private HealthScript _REFERENCE_NAME;

    Void Start(){
    _REFERENCE_NAME = GetComponent<HealthScript>();
    }
    Now i can type my reference name and put a dot syntax at the end and take a look at all the public fields.
     
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    I use them from time to time. There's use cases where it makes plenty of sense. The problem with them is that lots of people use them where they cause more problems than they solve, and that lots of people use them as crappy shortcuts in place of designing actually good systems. So experienced developers and teachers simply end up telling novices or students not to use them, ever.

    Plus, that's typically pretty safe advice, because even when they are an alright solution there are typically other solutions which are at least as good. Also, using them often suggests that you're not managing scope effectively.
     
  4. zaxvax

    zaxvax

    Joined:
    Jun 9, 2012
    Posts:
    220
    Good part of .NET, Mono and Unity is made of static classes, methods, properties.
    Do you have any better idea what to use instead of Color.white which is a static? Also libraries of functions, why would I need to instantiate a class if I only want to use a function, especially the one that accepts various objects as parameter. Don't get crazy with OOP guidelines. As long as your project is working and you don't get yourself lost in your code, then it's fine.
     
  5. schragnasher

    schragnasher

    Joined:
    Oct 7, 2012
    Posts:
    117
    I use them for my story database. We have a database of stories that we load and needs to be accessed by monobehaviors Somehow the monobehavior needs a reference to the database object. We could create a seperate gameobject that stores references to the databases in another monobehavior and give it to the necessary scripts, but that is a bit ugly so we made the database a static class. Since we only need 1 instance of the database this works just fine. An external logger is also useful when static.
     
  6. Pati-Co

    Pati-Co

    Joined:
    Jan 9, 2014
    Posts:
    56
    It is impotant to understand why "static is bad", if it's bad only because of increasing dependencies, then we should remember - not every dependency is bad - if class is not modifying (if it stable), such dependency is not bad. So, if your static classes, methods or variables are stable and will not change in the future - you can be calm about dependencies on it.
     
  7. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Well, the popular Singleton design pattern would be impossible without static variables. So you are "forced" to use them for some use cases. Another one is counting how many objects are alive, or using a readonly static member variable instead of a const for a reference type since this is not allowed (only for string).
    So there are valid use cases for static variables and they should not be banned completely (like goto fe) but you should also use them carefully and check wether there is a better solution available. The biggest downside of using static for "easy access" is to couple your classes together so you can't (re)use them independently. But providing access between classes and let them use each other is a big problem anyways and current attempts (IoC, DI) try to solve this but not yet satisfying IMO.
     
  8. Elias.W

    Elias.W

    Joined:
    Jun 13, 2014
    Posts:
    2
    Thanks for the replies! Static classes seems to be okay to use as a last resort and if there is no risk involved when using them. And about SubZeroGamings solution, when I used GetComponent in my program it generated a NullReferenceException error. Probably because the two scripts are residing in their separate gameobjects, so I am guessing that I A) also have to reference the gameobjects that are using 'script 2' or B) That or I've done something horribly wrong.
    Here is the code:

    //Script 1
    public class GravityObject : MonoBehaviour {

    [HideInInspector]
    public Vector3 gravityObject;
    private RaycastHit hit;
    private GravityPointScript referenceName;

    // Use this for initialization
    void Start () {
    referenceName = GetComponent<GravityPointScript>();​
    }​

    // Update is called once per frame
    void Update () {
    gravityObject = transform.position;​

    Debug.DrawRay(gravityObject, referenceName.gravityPoint - transform.position); //This is the line causing the NullReferenceException error​

    }​
    }

    //In script 2, all I did was removing the static keyword.

    If we were to say that explanation A) was right, I would not want to reference all of my gameobjects using script 2 because I wanted to create something easy to use, so you would only need to add the scripts to your desired objects and everything would work. I thought about using FindGameObjectsWithTag(or name) but I've heard that that method is really slow. It would also mean that objects using script 2 would all have to have the same name or tag, which I don't want to happen.

    Will I be forced to use static variables or is there another way? I couldn't get GetComponent to work properly, have I done something wrong? I am thankful for all the help you've given me and I would appreciate if you could keep helping me solve this. :)
     
  9. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    It's also a constant, and as such actually has nothing to do with the whole "static is bad" thing - it neither increases dependency or opens things up to "global scope".
     
  10. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    In terms of Unity, I use static variables when I don't want to lose data between scene loads. If you need data to persist between scenes then use statics. If you don't care about losing data between scenes then don't use statics.
     
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    There are plenty of other avenues for this as well, though.
     
  12. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Effectivly static variables arent bad itself. Therefore I dont quiet get why its always mentioned that they are. Static fields, methods, properties and classes are fundamental feature of .net. Especially when designing singletons. Its completly legit to use them as long as you do it right.

    From another point of view, why static's might be considered bad. Most of the time, beginners might use static's just as a shortcut to accses a field from anywhere. However, when getting the hang of OOP, one will start to use static's correctly.

    All of it is about how you use them and in which context. For example, creating a class with a static "name" field, of which class only one instance exists and which's field is local to that instance, is considered bad design.
    Static fields, by design, are meant to share data across every instance of that certain type. In general, static fields reflect data which is common to every single instance. Best example, a. instance counter for a certain class would be static since thats data which is always the same and shared across all of them.

    Point is, static's are completly legit, you just have to distinguesh cases.
     
    User340 likes this.
  13. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    This discussion just brought up an interesting thought to me, what would it be like if there were no statics? If you could only do stuff on instances of objects, and that's it. Could software still be written?
     
  14. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    Yes ofcourse.
    Though static variables are somtimes convinient, they can always be replaced by another solution.
     
  15. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Yes, it would of course be possible but legit static cases would simply produce bad code design. Delegates could be ditched aswell, creating cluttered up switch statements. Same goes to switch itself which could be replaced with if-elseif-else.
     
  16. Pati-Co

    Pati-Co

    Joined:
    Jan 9, 2014
    Posts:
    56
    Any application (before WIN8) has to have one entry point - for .NET applications it is method Main(), and this method is static. :) So you could write a software, but you cannot run it...
     
  17. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Right, I know about the Main() method. But if we assume that the program was run by invoking a classes constructor instead.
     
  18. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    Forgot about that one :rolleyes:

    And also, class constructors are static as well, or not?
     
  19. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Exactly, I was about to mention constructors as well. They're semi-static in that they can be invoked from anywhere, like a static, yet they have access to instance members, like non-statics.
     
  20. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    No... Its acctually hard to say what normal constructor belong to. Tho, there are normal constructors to instantiate an instance of a class, and static constructors which get called by the CLR when an object of that certain type (or field of that class) is first used.

    By default constructors should be considered non-static.