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?
Generally, static variables are used because the value remains between scenes. You can just name it a regular variable but it won’t do that anymore. There are a lot of ways to keep variables between scenes, you could check out this video on persistence:
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.
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.
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?
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.
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.
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:
public class MyTest : MonoBehaviour
{
TestScript ts;
private void Start()
{
ts = this.GetComponent<TestScript>();
Debug.Log(ts.getWordValue());
}
}
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.
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.
Show us the code where you are calling getWordValue and getting null. That’s in a different script than TestScript, right?
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.
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.
Pasting your code again here for reference.
public class TestScript : MonoBehaviour
{
string word;
Start
{
word = "updated";
}
public string getWordValue()
{
return word;
}
}
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?
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
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.
I put a Debug.Log in the TestScript Start method and it printed it out, however the other value is still null
Okay, after actually putting your code in to test it myself, I noticed your
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.
That fixed it, thank you so much
You can also access your TestScript object using GetComponet(), 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.