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

Getting values without static variables?

Discussion in 'Scripting' started by UniversalGesture, Oct 6, 2018.

  1. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    My script has methods which return values, unfortunately they don't work unless the value I'm returning was declared as a static variable. How can I solve this?
     
  2. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
  3. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Wouldn't static variables cause problems since there can possibly be other variables with the same name throughout the project? That's why I wanted to avoid using them.
     
  4. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    If you’re having to declare a variable as static for the method that uses it to work it means the method itself is static. You can’t access an instance variable from a static method. If you don’t want to use static, make both the method and variable non-static. Of course, this will require you to have an instance of the class to call the method.

    I’d say the main reason not to use static is because it can lead to annoying bugs and make it harder to debug the program - you want to try to minimize the places in the code that affect some other code so that when something breaks with that code you quickly know where the problem must be.

    That doesn’t mean static is always bad. It’s fine for functions that don’t modify outside variables such as math functions. It can also be fine in my opinion to have a private static variable when you actually want a variable to be shared between all the instances but not accessible outside of the class. But do make sure you know what you’re doing if you use it that way.
     
    UniversalGesture likes this.
  5. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Thanks for your advice. I created a new instance of the class but when I call the method the value returned is always Null. It seems the variable my method is returning is always null, even though it gets changed in Start, why is this?
     
  6. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    If the class has a Start method then I'm guessing your class is a MonoBehaviour. In that case, you shouldn't be 'creating' an instance of it unless you meant by using Instantiate - MonoBehaviour instances are created by Unity. I'd have to see your code since I'm not really sure what you're doing.
     
  7. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Your right that my scripts are both mono behavior.

    Here is basically what I have

    public class TestScript : MonoBehaviour
    {
    string word;

    Start
    {
    word = "updated";
    }

    public string getWordValue()
    {
    return word;
    }
    }

    No matter what I try I get null.
     
  8. DungeonBrickStudios

    DungeonBrickStudios

    Joined:
    Jun 9, 2015
    Posts:
    69
    Could be something to do with script execution order (which you can control via edit->project settings->script execution order).

    I actually tried out the code above, calling "getWordValue()" from a different class after getting an instance of testscript from that same gameobject. See code:

    Code (CSharp):
    1. public class MyTest : MonoBehaviour
    2. {
    3.  
    4.     TestScript ts;
    5.     private void Start()
    6.     {
    7.         ts = this.GetComponent<TestScript>();
    8.         Debug.Log(ts.getWordValue());
    9.     }
    10.  
    11. }
    It did indeed return null because getwordvalue ran before the Start() of TestScript ran for some arbitrary reason.

    But, having set TestScript to run some milliseconds earlier than the average script, I stopped getting nulls and it worked as expected. I set it to -500 milliseconds, but I think -100 or even -50 would be just as well too.
     
  9. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    The problem for mine however is that it always returns null no matter how long I wait.
    The variable never changes it's value. Not sure why though.

    I'd like other users to be able to get and set public values in my script using methods.
     
  10. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,335
    Show us the code where you are calling getWordValue and getting null. That's in a different script than TestScript, right?
     
  11. DungeonBrickStudios

    DungeonBrickStudios

    Joined:
    Jun 9, 2015
    Posts:
    69
    Not sure it's a matter of waiting though, as I had it constantly returning nulls even in the update method before I changed script execution order.
     
  12. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    Your right yes, different scripts.
    It's just a simple mono behavior script that calls the method in the Update.
    All of this is for testing purposes.
    I just want to know how I can get and set values between scripts without static variables, which is why I'm trying to use methods.
    I think what I'm asking should be fairly straightforward and essential in most projects.
     
  13. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    Pasting your code again here for reference.

    Code (CSharp):
    1. public class TestScript : MonoBehaviour
    2. {
    3. string word;
    4.  
    5. Start
    6. {
    7. word = "updated";
    8. }
    9.  
    10. public string getWordValue()
    11. {
    12. return word;
    13. }
    14. }
    First of all, that should be void Start() not just "Start". I'm assuming this isn't what you actually put in your code file or you'd have a compile error.

    Assuming that's correct, this code is correct. You have a private variable, assign it in the start method, and then call it in your method.

    Assuming that getWordValue() method is being called from an Update method in another script and is returning null, then the only problem I can think of is that your Start didn't get called.

    So either you defined it wrongly and Unity didn't call it or the MonoBehaviour isn't active in the scene. Did you actually confirm that the word = "updated" line in Start is even called?
     
  14. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    This is the script that calls the method, and your right about the Start missing the "()"

    public class TestCall : MonoBehaviour {

    TestScript obj = new TestScript();

    // Update is called once per frame
    void Update () {
    Debug.Log(obj.getWordValue());
    }
    }

    However it still returns null
     
  15. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    If you put a Debug.Log statement in TestScript's Start method, does it print anything?

    If it's null despite being assigned in the Start method, it either means the Start method wasn't called or some code not being shown changed the value back to null.
     
  16. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    I put a Debug.Log in the TestScript Start method and it printed it out, however the other value is still null
     
  17. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    Okay, after actually putting your code in to test it myself, I noticed your

    Code (CSharp):
    1. TestScript obj = new TestScript();
    line. You're not supposed to make a MonoBehaviour with the 'new' keyword.

    You need to put the TestCall script on a game object in the scene to create it correctly.
     
    UniversalGesture likes this.
  18. UniversalGesture

    UniversalGesture

    Joined:
    May 29, 2017
    Posts:
    125
    That fixed it, thank you so much
     
  19. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,335
    You can also access your TestScript object using GetComponet<T>(), as in:
    TestScript obj = GetComponent<TestScript>();


    a MonoBehavior is a component and you can use GetComponent to get a reference to any particular type of component that is on the same GameObject.