Search Unity

Help with understanding Statics

Discussion in 'Scripting' started by DarkEcho, Nov 18, 2014.

  1. DarkEcho

    DarkEcho

    Joined:
    Jul 7, 2014
    Posts:
    233
    Still confused with Statics,

    1) What is the purpose of a Static?

    2) Where/When should I use a Static?

    "Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object." - MSDN

    Yeah thats a rather Dull/Blunt (I need to find a less rude word for 'lacking explanation', forgive me).

    Ok so I know its used on Class's/Functions & Variables and it makes a script/class an individual (Lacks explanation)

    Cheers!
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    When you create your classes, you often want to instantiate them in order to have individual objects.
    If you were about to create a class 'Person', you would want to create several persons each with its own information such as age, name and so on.
    These attributes are defined for instances, thus called instance variables, also called non-static variables.

    Another example, let's say you create a class 'TenLitreBucket'. You'd want to have each object of that class to hold the information about the current fill level. The first instance may be filled with 5 litre, the second 7.5 litre and you can change that for each bucket individually by adressing the object via a reference to it.

    Now, a bucket usually has a certain limit it can be filled up to, you can add a variable to that class in order to check if the limit is reached or not. You could do that for every bucket, which would make sense if they were of different sizes, but as we deal with ten litre buckets only here, it's enough to have one variable to hold the information.

    This variable, also called class variable or static variable, is defined for the class, rather than for the instances. For this reason, instead of the need to address a specific object of the class, you can now access that field through the classname directly. Note that this is just an example, you often use methods (or properties) to access and retreive the values of editible fields in order to fullfill the principle of encapsulation.

    So, why do you even want that if you could implement it for every object? Static methods and variables are only created once per class, if you have zero objects, you'll still have that method/variable. If you create 1 million objects, you'll still have static variables and methods only once, not a million times (instance variables would be created once per object). That can save memory, but it is also useful for carrying information that several objects operate with.
    Short example: Within one class you could count the number of instances created with a static variable, using a non-static field that would maybe not be impossible but totally complicated regarding the simple solution using a static field.

    You can do the same with methods btw, if you have a look at the Math class that comes with almost every programming language, you'll notice it offers alot of static methods. That's due to the simple fact that you do NOT need an individual object in order to calculate the sin, cos, square root or whatsoever. It's enough to have one method which operates on the classes level. You can access those via ClassName.MethodName().

    There's quite alot to tell about static methods, variables, classes etc but you have to try things out in order to fully understand it.
    Please note that 'static' can have several different meanings in other programming languages such as C++.
     
    Senshi likes this.
  3. Kirk Clawson

    Kirk Clawson

    Joined:
    Nov 4, 2014
    Posts:
    65
    This question is somewhat related to your other question of "What is an 'Instance'", so I will phrase this in a way similar to the answer over there that clicked the light for you.

    A class template can have two types of variables (or functions - but we'll limit this to variables for now): an instance variable, or a static variable.

    An instance variable is not shared. Each time you create a new instance of your class template, the instance variable can hold a different value for each of them.

    Conversely, a static variable is shared. You can think of it as a global variable. No matter how many instances you create, the value you stick into your static variable will be the same for all of them. In fact, you don't have to create any instances to use a static variable.

    I think some code might help here. Given this class:
    Code (CSharp):
    1. public class Foo {
    2.     public string MyInstanceVar;
    3.  
    4.     public static string MyStaticVar;
    5. }
    You could use it in this fashion:
    Code (CSharp):
    1. Foo f1 = new Foo(); // f1 is an instance of class Foo
    2. Foo f2 = new Foo(); // f2 is a second instance of class Foo
    3.  
    4. f1.MyInstanceVar = "Hello";
    5. f1.MyStaticVar = "World";
    After that code has run, f2 will still have an empty MyInstanceVar variable. But f2.MyStaticVar will be filled with "World".

    There is of course a much deeper discussion to be had on statics and what their implications are, but I think this should get you pointed in the right direction.
     
  4. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    Have a look at your Instance-thread where lordofduct gave a pretty nice example of instances.
    http://forum.unity3d.com/threads/what-is-an-instance.279537/#post-1844893

    Now statics are more or less the other thing. They are not _a_ human, they are THE human (though this is a bad example, since this suggests that there might be other humans, which is not the case). Statics are a one-of-a-kind thing, you cannot have multiple incarnations ( = Instances) of statics, no matter whether you put that on a property, a class or a method. It will only live once in the memory, and any change to the static is reflected in all areas where you use it.
     
  5. DarkEcho

    DarkEcho

    Joined:
    Jul 7, 2014
    Posts:
    233
    Ok, so a Static when used with scripts/variables, it becomes THE script, where all variable values are the same, regardless of where they are used.

    I also noticed while trying to figure them out that they cannot be used when inheriting from monodevelop. so that answers my question of where/when they are used.

    Have i got everything correct?
    Anything im missing?
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No... static variables and methods can be used with classes inheriting from MonoBehaviour (which is what I think you meant), just as with any other class.
     
  7. DarkEcho

    DarkEcho

    Joined:
    Jul 7, 2014
    Posts:
    233
    Are you sure this is correct?
    When I remove inheriting from MonoBehavior, it fixes the problem...

    Unless "Static classes must derive from object" is a hint although I dont get it, the relationship of Statics & Objects....I keep bumping into these now...

    using UnityEngine; //Berg Zerg 128, remember to remove

    public static class StaticTest : MonoBehaviour{

    public static Item CreateItem(){
    Item temp = CreateBag();

    //temp.ItemName = PlayerInteraction3D.hitInfo.collider.gameObject.GetComponent<Item> ().ItemName;
    //temp.ItemDescription = PlayerInteraction3D.hitInfo.collider.gameObject.GetComponent<Item> ().ItemDescription;

    return temp;
    }

    private static Bag CreateBag(){
    Bag temp = new Bag ();

    temp.ItemName = "Bag: " + Random.Range(0, 100);
    temp.ItemType = Item.type.Bag;

    return temp;
    }
    }

    'Item' & Bag scripts are simmiler to each other, heres 'Item'

    using UnityEngine;
    using System.Collections;

    public class Item : MonoBehaviour {

    public string ItemName = "";
    public Texture2D InvItemIcon;
    public string ItemDescription = "";
    public Mesh ItemModel;
    public type ItemType = type.Misc;
    public rarity ItemRarity; //???
    public int ItemCost = 0; //???

    public string itemID = "";

    public int ItemWeight = 0;
    public int ItemQuantity = 0; //???
    public bool Stackable; //???
    public int MaxStack = 20; //???
    public int TakenSpace = 1; //???
    public bool Tradeability = false;
    public bool Equippability = false;
    public bool Respawn = false;

    public bool item3d = false;

    public float respawnTime = 60f;

    public enum rarity {
    Always,
    Common,
    Uncommon,
    Rare,
    VeryRare,
    SuperRare
    }
    public enum type {
    //Weapons
    Weapon,
    //Armours/Clothes
    Helmet,
    Armour,
    Gauntlets,
    Palodons,
    Legs,
    Boots,
    //Other
    Misc,
    Consumable,
    Bag,
    Pouch,
    sleepingBag,
    Ore //Must have Ore otherwise how would the smelting/smithing system work?
    }
    }
    }

    Ignore the comments, they dont mean anything. (Just notes)
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Ah, I see the confusion — you're trying to create a static class, which is a class in which all the members must be static, and which can't be instantiated. No, you can't do that.

    But you can declare static variables and methods in any ordinary (non-static) class, including classes derived from MonoBehaviour. Such a class can be instantiated, but the static variables and methods are called on the class itself, not on any instance.
     
  9. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    You can use static as a modifier for variables and methods in a non-static class which inherits from Monobehaviour.

    As a monobehaviour has to be attached to gameObjects, which is equal to creating instances, you cannot make a static class which inherits from MonoBehaviour, as you are not able to instantiate static classes.
     
  10. Stoven

    Stoven

    Joined:
    Jul 28, 2014
    Posts:
    171
    "Are you sure this is correct?
    When I remove inheriting from MonoBehavior, it fixes the problem..."

    If you reread Joe's post:

    He means you can do this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MyClass : Monobehaviour
    5. {
    6.  
    7.     public static int someStaticInt = 0;
    8.  
    9.     public static void SomeMethod()
    10.     {
    11.         Debug.Log("SomeMethod executed");
    12.     }
    13. }
     
    Last edited: Nov 23, 2014
    JoeStrout likes this.
  11. DarkEcho

    DarkEcho

    Joined:
    Jul 7, 2014
    Posts:
    233
    Ok I think I now have it. To summerize...

    • A class can be Static however all methods/variables must be static to
    • Methods & variables can be static without the class being static
    • Statics makes all variables the same value (THE variable)

    I also had a problem with the following error 'An object reference is required to access non-static member'
    which I finally understand, i was getting a value from A script that wasnt static, so I could etheir make it static or give the script a specific path to the required value (Which was the desired solution)
     
    JoeStrout likes this.