A small s&box habit with a big payoff.

The problem
Looking it up every frame.
protected override void OnUpdate(){ var cc = Components.Get<CharacterController>(); cc.Move();}
Components.Get searches this GameObject's components. In OnUpdate, that's the same search every frame.
The fix
Find it once. Keep it.
The controller isn't going anywhere. Look it up when the component starts, store it in a field, and reuse it.
OnStart→find
OnUpdate→reuse
The fix in code
Cache it in OnStart.
CharacterController _cc; protected override void OnStart(){ _cc = Components.Get<CharacterController>();} protected override void OnUpdate(){ _cc.Move();}
One search when the component starts. Every frame after that is just a field read.
Even simpler
Let the editor wire it up.
[Property] public CharacterController Controller { get; set; }Drag the component into the slot in the inspector. No lookup in code at all.
Watch out
Cached isn't forever.
If the component gets removed, your field still points at it.
- Component removed
- field goes stale
- Check before use
- if ( _cc.IsValid() )
The rule
Look it up once, reuse it forever.
- Find
- in OnStart
- Store
- in a field
- Use
- every frame