What to use instead of GameObject.Find and GetComponent
Hello!
So what Ive learned throught my time in Unity is not to use GameObject.Find and GetComponent(). So what should I use instead?
Lets say I have a UI.Text component on a GameObject which is child of the canvas and I want to set the text value of it equal to my player's health through the script I have attached on my player, who is obviusly not a child of the canvas. What is the most efficient way to make this?
Answer by Socapex · Dec 31, 2015 at 06:45 PM
[SerializeField] PlayerHurtScript playerHurtScript;
// Somewhere
playerHurtScript.DoSomething(potato);
Drag the Player object onto the new field.
Note that GetComponent isn't bad in and of itself (especially with auto-caching). I agree Find is the devil, but mostly because it can silently break your game.
You can also have a "master" singleton that gives out references to important objects like player/score etc. You still drag the stuff on him though.
To add a little bit - if you're just hooking up a couple of things in a Start method there isn't really anything wrong with using these functions. You don't want to run them each frame though.
Exactly. I wouldn't worry to much about GetComponent (even in loops, because caching).
Find is bad, and it is a good thing to stay away from it. I used to say "use it reasonably", but after seeing so much atrocious production code, ppl using find in triple loops and all, I say it is a good decision to never use Find. Unity provides many alternatives.
It is often fun and interesting to theorize and brainstorm alternatives to Find anyways :)
Answer by callen · Dec 31, 2015 at 06:58 PM
Last time I checked the decompiled source, I saw that GetComponent is using an internal dictionary of Type->Components to make subsequent calls more quickly. (I think that's what Socapex's 'auto-caching' comment was referencing but not sure). Dictionaries should be fast enough in C# to not worry about calling multiple GetComponent()s every frame.
This doesn't necessarily happen with the GetComponentInChildren calls though, so I'd be more careful and keep a variable with those results. I've never used Find really, because I always heard it was the devil and I don't like keeping const string values in my code when I don't have to.
Most efficient way to do what you requested? I'd probably just put a script on the UI.Text itself that looks like this:
class HealthDisplay : MonoBehavior
{
//assigned in the editor, through drag-n-dropping your player object to it
public PlayerScript Player;
void Update(){
GetComponent<Text>().text = Player.health + " HP";
}
}
Your answer
Follow this Question
Related Questions
Value doesn't change in game when updated. 2 Answers
Why Does Prefab Loose UI elements on Scene Change 0 Answers
How do I shorten a gameObject.GetComponent 1 Answer
Move gameObject on UI Button Press 2 Answers