- Home /
Very basic optimisation question (Find)
Hi. I have a player with its references to its own components like collider/rb in a player.cs script. The thing is, referecing manually in the engine makes it look ugly, and I was wondering : Is referencing like rb = this.GetComponent<Rigidbody2D>();
is okay ? It may use a lot of ressources as a level of my game is composed of multiple scenes and there's no DoNotDestroyOnLoad object, so it searches anew in each scene.
It helps to keep cleaness in my inspector ^^', tough I can help a little with Headers.
Answer by julzerinos · Sep 14, 2021 at 09:44 PM
That's is actually the standard approach for objects not initialized in the inspector (dynamically, or in code-focused projects), but a key consideration is caching. If you're calling GetComponent every frame, that may lead to performance bottlenecks, especially dangerous as the number of attached components increases. You will be fine with caching the references and then just calling them as you need them.
See an example of how I set up my MonoBehaviors with Rigidbodies below. You can of course do this with any components.
[RequireComponent(typeof(Rigidbody))]
public class PlayerMove : MonoBehaviour
{
private Rigidbody _rg;
private void Awake()
{
_rg = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
_rg.AddForce(Vector3.forward, ForceMode.Force);
}
}
Yep, I'm calling once in the Start() function, but I was considering if it's heavy because I'm going a speedy-game where you basically "swipe areas as fast as possible", and a level is made of multiple scenes. Sorry for not giving that detail in the question, I understand this mistake and won't do again.
My game is very similar to Hotline Miami if you want a visual example :
No worries, but I still would say that this is a negligible cost. Of course it depends how often you load a new scene. Using the inspector to set the values might be a tiny fraction faster, as Unity is just injecting the value before Awake or Start, whereas in those event functions you have to spend a bit of processing power to find the components. IIRC GetComponents logic is to loop through all the components with a stop condition on the component type, so depends on the component count.
One other consideration - I assume this is the player rigidbody we are talking about right? The way I would approach it is to keep the player alive across all scenes. You can use DontDestroyOnLoad for that. Then the player script remains the same instance and your rigidbody reference should remain the same.
One remark to the remark - you can also load scenes additively (on top of existing scenes). It's also worth taking into account that transferring the logic for adding new objects instead of scenes may keep things in check as well.
Hope this helps. In the end the best answer to optimization is one you have to answer yourself - open up the Profiler (it doesn't bite) - plop in some Profiler.BeginSample
and observe the differences.