Hi,
Sorry this must be so simple.
I want to create a variable in a script that is accessible (read only is fine) to all other scripts. I am currently using JavaScript, although I am considering moving accross to using C#.
Martin
Hi,
Sorry this must be so simple.
I want to create a variable in a script that is accessible (read only is fine) to all other scripts. I am currently using JavaScript, although I am considering moving accross to using C#.
Martin
I’ve sort of found a hack for this one, but I’m sure there must be a better way. Currently I have an empty game object called Globals that has a script called Globals attached to it. I then GameObject.Find and use .GetComponent in all other scripts that need access to these global variables.
Is there a better way of doing this?
Declare your var as static in the Globals.js script. E.g. static var someVar = 0;
You can now access the var everywhere as:
Globals.someVar
Generally you’ll want to avoid GameObject.Find if you can as it’s rather slow.
Thanks! I knew there had to be an easier way
Thanks! Believe it or not, I did not comprehend before that “static” in Unity/JavaScript works like “global” in Director. (I had already figured out that a Unity global is actually local to the script )
I had been using the method of drag-and-dropping an obect into the inspector of EVERY scripted object that needed to access a certain variable. Now I’ll rewrite to use statics, and save myself a lot of drag-and-dropping.
This might be a good point to explain clearly in tutorial/beginner docs.
So is the following approach a good one? Have I got this right?
* If you need to share a variable with just ONE other object it is best to use this code in the other object:
var myobjectname : GameObject;
myobjectname.somevarnamefromthatobject = whatever;
(That’s to change the value, but you could also just read it. Or, use your scriptname as a class, as I have been known to do?)
And then drag the first object into the myobjectname slot in the inspector of the second object. (And myobject name doesn’t REALLY have to match the object or script name at all, it can be anything, and the reference will simply connect to whatever you dropped.)
* But if you need to share a variable with a LOT of other objects, it is best to use this in the code if the first object:
static var varname = whatever;
And in all the other objects that need to change (or you could just read) that value:
thatscriptname.varname = whatever;
(Where thatscriptname is the actual script filename, minus the .js ending.)
Is that a reasonable basis for deciding between the two methods?
Now, I still don’t fully grasp the reasons one would choose between these two drag-and-drop inspector options:
var myobjectname : GameObject;
(As described above, with GameObject being the class.)
Versus:
var myobjectname : thatscriptname;
(Where thatscriptname is used as the class, and is the actual script filename, minus the .js ending.)
I would have thought that using GameObject would have the benefit that you don’t JUST get access to the script and variables, you can access the object’s transform and other properties too. But… I find you can access the transform just fine even if thatscriptname is the class. You can still move and rotate the object.
And then sometimes I have used:
var myobjectname : Transform;
And then I can access the transform… but I could have done that with the other two methods anyway.
How do you choose which is best? When should you reference a GameObject vs. a script-class vs. a Transform? It seems like GameObject could do everything all the other methods could do.
Is there a performance reason? Just personal preference?
My game works fine without me knowing, but I’d rather have the best code I can create
I’d recommend always exposing the variable type which you are actually using in your script.
eg.
var myobjectname : GameObject;
myobjectname.GetComponent (thatscriptname).variableName = 5;
is possible but why would you do that, if you can write:
var myobjectname : thatscriptname;
myobjectname.variableName = 5;
And yes, the second method is also faster.
So generally expose the variable which you actually use in the script.
Another nice aspect is that if you eg. expose a
var some : Rigidbody;
Then you can only drag game objects with rigidbodies. If you had a game object, you could always drag it on but then you get a runtime exception when using the result from GetComponent.
So by exposing the right type you spot setup errors quicker.
I think that makes sense… and there are probably a lot more classes you could use for drag-and-drop than I know. I’ve never thought to use : RigidBody for instance.
Once I’m sure my head is around this topic (give it time) I might try to write a beginner’s topic for the Wiki covering ALL the ways of sharing data between scripts and objects, and why you might choose each. I’d even mention Prefs, if the retrieval is intended to be long-term. Some kind of big-picture article to dodge the dangers of learning ONE way to do something and then (like I tend to do) over-using it in other situations.
You can use drag and drop for every class that derives from Object (See the script reference class table) or any script.
(Eg. you can also have references to a Shader or Texture)
Other classes or structs (eg. Vector3) are directly embedded in the inspector.
Is there any way to use var myobjectname : myscriptname;
and reference the GameObject it’s attached to without using GetComponent()? I ask only for efficiency’s sake.
Just type
myobjectname.gameObject
:o. The modesty required to realize that almost makes me wish it actually was convoluted and difficult .