The problem
GameObject.Find() searches the scene for a GameObject by name. That can be useful for occasional lookups, but it becomes a poor fit when the call sits inside frequently executed code.
Avoid searching every frame
void Update()
{
var target = GameObject.Find("Player");
if (target != null)
transform.LookAt(target.transform);
}
This repeats the scene search every frame. With many objects doing similar work, the unnecessary searches can add up.
Cache the reference instead
private Transform _target;
void Start()
{
var player = GameObject.Find("Player");
if (player != null)
_target = player.transform;
}
void Update()
{
if (_target != null)
transform.LookAt(_target);
}
Now the lookup happens once during initialization, while the frequently called code reuses the cached reference.
When to use something else
If the relationship is known ahead of time, an even better option is often to assign the reference through the Inspector or pass it into the component when the object is created. That avoids a scene-wide name search entirely.
Use GameObject.Find() for occasional lookups when appropriate, but do not put repeated scene searches in hot paths. Resolve the reference once and reuse it.
For the API details, see Unity's GameObject.Find documentation.