How does a game object keep track of its components and could we avoid GetComponent?

1 When I get a reference to a game object, how does it keep track of its components? Does every game object keep a list (reference to array-like structure) that keeps hold of the references to the components?

2 Suppose I have a reference to some game object that I’ve found - maybe I’ve done a raycast, hit some object A, and I would like to do something with it - if it has some “HitEffects” component, I’d like to call some particular method of this component. Generally, one option is to just call GetComponent.

This seems somewhat inefficient though - wouldn’t it be useful to have a direct, customizable reference to a specific component on the game object? For each game object we could just have a reference to one specific game component on this given game object, let’s call it “DefaultComponent”.

This way, if someone wants to, instead of having to call some generic version of _gameObject.GetComponent, they could just call _gameObject.DefaultComponent directly, pass in the proper arguments and have the object do what they want, or returning the reference to the component.

This isn’t a huge difference to using GetComponent, because in a lot of cases, the DefaultComponent will still have to do some sort of comparison to find what you’re looking for, but in a lot of cases this could be made far more efficient than a GetComponent that might have to go through 10+ components. I’m writing it out as an example of the direction in which I’m thinking.

For even more flexibility, why not just keep the components in some sort of ordered list? That way, I could just directly access say the “first” component of the game object, and I’d know it’s the one I want to use. Might be a bit messy to keep track of, but it could still be useful. Isn’t it also done with transform already anyway? I’d expect that a gameobject doesn’t actually search through it’s components to find the transform, but I wouldn’t exactly be surprised if it did.

//

All of this are just details, but I’m surprised something like this isn’t really possible. I know that if a raycast hits an object with “Enemy” tag, I’ll end up calling some method in the “HitEffects” component on the object, and this is what will always happen in the specific raycast. But despite the simple goal, I have to do a GetComponent.

There’s no problem calling GetComponent unless you’re calling it for every frame. Just cache it in Awake if you can.

When you collide with an object it’s fine to call GetComponent on it.

If you’re doing multiple GetComponent calls to the same object you might want to think about adding each of those objects as a property of 1 component.

E.g. if you wanted to access the and components of the game object, add a class which has Health and Movement as properties. Then you can call var creature = GetComponent(); and then subsequently creature.Health and creature.Movement.

1 Like

Yes.

Once upon a time we had these but there were two major problems with them. One, having hard references to them meant that builds had to include every system that they depended on even if you didn’t need them. Back when Unity first came out it wouldn’t have been that big of a deal but over the years the size requirements ballooned.

Two, people were caching them meaning the advantage of having to type less was literally only for a single line of code per script for the vast majority of developers. Since we were already caching them what advantage is there to being able to use the quick property accessor (Unity’s term) in Awake() versus GetComponent() in Awake()?

By the way nothing prevents you from doing this yourself.

using UnityEngine;

public class MyBehaviour : MonoBehaviour
{
    protected Rigidbody body;

    protected void Awake()
    {
        body = GetComponent<Rigidbody>();
    }
}
using UnityEngine;

public class Foo : MyBehaviour
{
    private void Awake()
    {
        base.Awake();

        Debug.Log(body.mass);
    }
}

Below is a link to the blog article discussing their removal.

https://blogs.unity3d.com/cn/2014/06/23/unity5-api-changes-automatic-script-updating/