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?

[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.

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";    
  }    
}