Skip to main content
Added note on search costs
Source Link
DMGregory
  • 136.3k
  • 22
  • 247
  • 373

The simplest solution is to take your initialization code and put it into Awake instead of Start. Like Start, Awake is guaranteed to run just once for each instance of a script (unlike OnEnable which can fire multiple times if the component is disabled and re-enabled)

But, like OnEnable (for already-enabled scripts), Awake runs before Instantiate or AddComponent return control to the calling method. So it behaves like a "pseudo-constructor", giving you an opportunity to prep all your script's dependencies so it's immediately ready to use by whoever instantiated it.

Or, you can do one better, and save doing this lookup at runtime at all, using a public or [SerializeField] private variable to wire up your references at edit time. When you instantiate, the deserializer fills-in these reference before Awake or OnEnable even run, very efficiently. You skip all the overhead of searching for the component reference at runtime (which isn't too costly individually, but does add up if you're awaking/starting dozens or hundreds of script instances on scene load).

If you miss the convenience of having the script find its own dependencies, you can have your cake and eat it too - both automatic wire-up AND no runtime component search. 🥳

The simplest solution is to take your initialization code and put it into Awake instead of Start. Like Start, Awake is guaranteed to run just once for each instance of a script (unlike OnEnable which can fire multiple times if the component is disabled and re-enabled)

But, like OnEnable (for already-enabled scripts), Awake runs before Instantiate or AddComponent return control to the calling method. So it behaves like a "pseudo-constructor", giving you an opportunity to prep all your script's dependencies so it's immediately ready to use by whoever instantiated it.

Or, you can do one better, and save doing this lookup at runtime at all, using a public or [SerializeField] private variable to wire up your references at edit time. When you instantiate, the deserializer fills-in these reference before Awake or OnEnable even run, very efficiently.

If you miss the convenience of having the script find its own dependencies, you can have your cake and eat it too - both automatic wire-up AND no runtime component search. 🥳

The simplest solution is to take your initialization code and put it into Awake instead of Start. Like Start, Awake is guaranteed to run just once for each instance of a script (unlike OnEnable which can fire multiple times if the component is disabled and re-enabled)

But, like OnEnable (for already-enabled scripts), Awake runs before Instantiate or AddComponent return control to the calling method. So it behaves like a "pseudo-constructor", giving you an opportunity to prep all your script's dependencies so it's immediately ready to use by whoever instantiated it.

Or, you can do one better, and save doing this lookup at runtime at all, using a public or [SerializeField] private variable to wire up your references at edit time. When you instantiate, the deserializer fills-in these reference before Awake or OnEnable even run, very efficiently. You skip all the overhead of searching for the component reference at runtime (which isn't too costly individually, but does add up if you're awaking/starting dozens or hundreds of script instances on scene load).

If you miss the convenience of having the script find its own dependencies, you can have your cake and eat it too - both automatic wire-up AND no runtime component search. 🥳

Source Link
DMGregory
  • 136.3k
  • 22
  • 247
  • 373

The simplest solution is to take your initialization code and put it into Awake instead of Start. Like Start, Awake is guaranteed to run just once for each instance of a script (unlike OnEnable which can fire multiple times if the component is disabled and re-enabled)

But, like OnEnable (for already-enabled scripts), Awake runs before Instantiate or AddComponent return control to the calling method. So it behaves like a "pseudo-constructor", giving you an opportunity to prep all your script's dependencies so it's immediately ready to use by whoever instantiated it.

Or, you can do one better, and save doing this lookup at runtime at all, using a public or [SerializeField] private variable to wire up your references at edit time. When you instantiate, the deserializer fills-in these reference before Awake or OnEnable even run, very efficiently.

If you miss the convenience of having the script find its own dependencies, you can have your cake and eat it too - both automatic wire-up AND no runtime component search. 🥳