Components Cache - edcasillas/unity-common-utils GitHub Wiki
Good practices indicate you should avoid usage of GetComponent methods in performance critical context. The preferred way to access components of a GameObject is to move the call to GetComponent to the Awake or Start method and cache the result, like this:
public class MyComponent: MonoBehaviour {
[SerializeField] private GameObject go;
private MyOtherComponent cache;
private void Start() => cache = go.GetComponent<MyOtherComponent>();
// ... then use "cache" instead of "go.GetComponent<MyOtherComponent>()" everywhere else in the code.
}
However, is not always possible to cache this reference. An example use case is when you're trying to take an action on a component of a game object inside the OnTriggerEnter
/OnTriggerStay
/OnTriggerExit
methods. You receive a collider as a parameter but you can't be sure it contains the component you require to take an action, so you might end up doing something like this:
private void OnTriggerEnter(Collider other) {
var player = other.gameObject.GetComponent<Player>();
if(player) {
// Take an action on the Player component
}
}
This is acceptable when the OnTriggerEnter method is executed by some object which will not have too many incidences, but if (for example) you try to put it in a moving object which will be possibly triggered by tons of other colliders, your code will have to make tons of allocations and lookups per frame. And things only get worse if you use this inside OnTriggerStay
.
The Components Cache offers a simple solution for this kind of cases by automatically creating a cache when replacing calls to GetComponent
to GetCachedComponent
. The example above would then look like this:
private void OnTriggerEnter(Collider other) {
var player = other.gameObject.GetCachedComponent<Player>();
if(player) {
// Take an action on the Player component
}
}
When you do this, a new game object called "ComponentsCache" appears in the hierarcy. This game object will store all the references you've retrieved using GetCachedComponent
during the execution of the current scene, so every subsequent call to this method won't create any allocations. No other setup is required.
The ComponentsCache object is destroyed (and all cached references are cleaned) when the scene is unloaded.