- Home /
Optimising references to other scripts
Hi there, I am making a game in which lots of different scripts on the same game object will reference each other frequently. So I am wondering what the best way to do this is for performance.
So first off, is referencing a variable from another script using:
variable = GetComponent<OtherScript> ().otherVariable;
any slower than referencing a variable from the same script, ie:
variable = otherVariable;
Secondly, though I guess the first question will answer this one... If I am using a variable from another script multiple times in each update/fixedupdate, would I be better off constantly referencing the variable from the other script, or would I be better off saving the variable as a variable within the same script first, and then referencing that? For example, which would be quicker:
this....
void FixedUpdate () {
LookForFood ();
}
void LookForFood () {
if (GetComponent<AI> ().targetSearch == Vector3.zero || Vector3.Distance (transform.position, GetComponent<AI> ().targetSearch) < GetComponent<AI> ().searchDistance)
NewSearchTarget ();
}
void NewSearchTarget () {
GetComponent<AI> ().targetSearch.x = transform.position.x + Random.Range (-GetComponent<AI> ().searchRange, GetComponent<AI> ().searchRange);
GetComponent<AI> ().targetSearch.y = transform.position.y + Random.Range (-GetComponent<AI> ().searchRange, GetComponent<AI> ().searchRange);
}
or this...
void FixedUpdate () {
search = GetComponent<AI> ().targetSearch;
distance = GetComponent<AI> ().searchDistance;
range = GetComponent<AI> ().searchRange;
LookForFood ();
}
void LookForFood () {
if (search == Vector3.zero || Vector3.Distance (transform.position, search) < distance)
NewSearchTarget ();
}
void NewSearchTarget () {
search.x = transform.position.x + Random.Range (-range, range);
search.y = transform.position.y + Random.Range (-range, range);
}
I know the latter is easier to read, but in this case it wouldn't matter too much because this script and similar ones are going to be about this short.
Answer by Dave-Carlile · Jun 20, 2015 at 04:10 PM
In general you don't want to call GetComponent
each frame because it has to search through the list of components on the target object. You should grab the component references you need once in Awake
and save them to variables, then just use the variables.
So the latter of your two examples is better, but move the GetComponent
calls out of FixedUpdate
and into Awake
.
edit: and by Start
I of course meant Awake
.
Ok cool, thanks! Been wondering about this a while. I haven't ever used Awake, I'll look that up. As for the GetComponent calls, I need to keep them up to date, so they might have to be called in FixedUpdate, but I should probably add an if statement to check before calling them trigger to call them in the FixedUpdate.
Are you changing the AI component that's on the gameobject, or are you just getting updated values of the AI propertes, e.g. targetSearch
? I would expect the latter.
In that case, you still don't need to call GetComponent
in FixedUpdate
.
AI ai;
void Awake()
{
ai = GetComponent<AI>(); // get a reference to the AI component
}
void FixedUpdate()
{
// get updated target values using the ai reference we already have
search = ai.targetSearch;
distance = ai.searchDistance;
range = ai.searchRange;
}
To repeat, you get the component reference once and store that in a variable. Then you can just access the properties off of that reference.
This just occured to me this morning while working on another script where I'm trying to make and access a list of scripts (and failing, but that's another matter!). This way does make the most sense under the circumstances, rather than keep picking out single variables, just reference the whole script, especially as all the references should only be to the AI script, and I'm gonna have a ton of scripts all doing this at once :D
Thank you for your help budddy!
Pete
Is there another way of referencing a script? using the declairing variable AI ai works fine for this script, but what if I want to declare a "variable" that could be any monobehaviour script, like in my list of scripts? I've tried type Component, $$anonymous$$onoBehaviour, GameObject, Object and probably some others already but I'm not having any luck with any of these. To clariy, I'm talking about something like this:
$$anonymous$$onoBehaviour ai;
void Awake () {
ai = GetComponent<AI>();
}
as I said above, none of the types I've tried in place of $$anonymous$$onoBehaviour seem to work properly
edit:
the only work around I can think of is to create a new script and reference each script individually in the new script, then reference, the new script and access the rest of the scripts through the new one. Seems like a long way of doing it though!
The problem with this approach is that you could only access properties on the $$anonymous$$onoBehaviour
object, unless you cast it to the script you're interested in, e.g. ((AI)ai).targetSearch
. It starts getting kind of messy.
Your answer
Follow this Question
Related Questions
Alternative to getComponent? 3 Answers
Is calling GetComponent multiple times bad? 2 Answers
Job System, workers are idle even though Asked to complete 0 Answers
Help with Optimizing Voxel Code? 1 Answer
GPU Instancing performance variation 3 Answers