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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Short Question: Should I use static var or Find the component

Discussion in 'Scripting' started by Bellwar, Aug 15, 2018.

  1. Bellwar

    Bellwar

    Joined:
    Aug 15, 2018
    Posts:
    8
    Code (CSharp):
    1. public class MyScript : MonoBehaviour {
    2.  
    3.   public static MyScript myScript;
    4.  
    5.   public void Awake() {
    6.     myScript = this;
    7.   }
    8. }
    So if I make a script somewhere else and I need to use a function in MyScript that isn't static I always do it this way. I looked around and another method of doing it is, always use somehow GetComponent<MyScript>() and use that. I just read this is slow.

    For example: I have a 2D collider on a button so that when a mouse goes over it it will show how stats change. This needs to access other classes, so I just made a script for each Button that calls the main class (another script) where the main method is. Should I on each button use Find and store the script/class as var x and then x.Method() or should I use MyScript.myScript.Method()

    I don't have much experience with programming and I just do it for fun and my personal learning. I just can't find info about what is the best way. I feel like it depends. If the class is small or if it is used from all over... control script or data (like stats etc.), make a static variable of that class. If there is a lot of code use GetComponent<>(). Now, I have each button to use GetComponent or make it static just for this one use in each button. Am I correct with my assumptions?

    Thanks for any help.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,378
    The problem with the 'static' option is only ONE instance of MyScript can be accessed.

    So lets say 'MyScript' is your enemy script. What if you have multiple enemies? How do you get a reference to each individual enemy?
     
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    GetComponent isn't really that bad performance wise unless you're calling it a lot, and you can cache the reference after you call it once anyway. What you don't want to do is call GetComponent every time you want to access that component.
     
  4. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,914
    The first way, you have to use Myscript.myscript to find it. Then, as you note, the second way has that long GetComponent. You could do it in a simple Unity way:

    In your script add "public Myscript myscript;". Then drag the gameObject with Myscript onto it. Now myscript will aim there (it works since drags check the type of your variable. If it's not gameObject they'll search inside and link to that).

    The drawback to that is you have to do it for every script that needs to use myscript. But you may not have many.
     
  5. Bellwar

    Bellwar

    Joined:
    Aug 15, 2018
    Posts:
    8
    I know. It's script about controlling the buttons for example and I need it to be central, in other scripts, I even have destroy if they get loaded again. It's something along if myScript == null ... myScript = this else Destroy(this). I have that from a tutorial about persistence, but wasn't sure if it's correct to make many static variables for each script when I need it outside.


    I like this option a lot. Might use it as well. It sounds really good.

    Ok I am really happy from this, thanks for all the options.
     
  6. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,140
    as for the solution that Owen described, you can keep your encapsulation tight and do it like this instead:

    [SerializeField]
    private Myscript myscript;

    The static solution is also called the Singleton pattern and is somewhat controversial. See the link for an example of how to use this more consistently across your project as well as a further link to the Toolbox pattern as an alternative.
     
  7. Bellwar

    Bellwar

    Joined:
    Aug 15, 2018
    Posts:
    8
    This is so hard to understand when you have like 20 hours into C# and Unity... Ups. I think I get the idea and points but have no idea how to implement the other better ways of doing it. Still many thanks for all the info.

    EDIT: So, after more research... If I understand it correctly I can use the static BUT I have to be really careful to not create second or more instances. If I make MyScript() {} protected and won't open the file again it should be ok.

    In the first place, I'm using this just because I want to have one place where I store the data about a user and modify it inside this same class. So I think I got it correctly.

    This was a very educational morning for me. Thanks.
     
    Last edited: Aug 16, 2018
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,914
    Singleton is sort of like a way to prevent your pet shark from chewing on your gold bars -- it's can be a serious problem, but it's for a specific situation.

    It's a way to make sure you have one of something. Well, in basic Unity, make 1 gameObject, drag 1 copy of the script onto it, and done. Not a problem at all.

    What happens is, you might need to _create_ that one object while running -- for example you need to run set-up code. So it has to be someone's job to do that. And you have a huge multi-part program where a bunch of people are trying to make it. They might all make one, or all assume that someone else did. Imagine an old-timey woman with 9 husbands who says she need a wash-board.