Hi, I am developing a puzzle game in Unity. I am a software engineer and as such I’m rarely happy with my code, so I tend to do a lot of refactoring. I get the idea of components pattern and I am adapting to it. However I am wondering how much some things that I do affect a game’s performances. In particular:
- How much do virtual calls weigh? Especially virtual reserved methods like Awake, Update, etc…
- Is it ok to call algebraic functions like dot products, plane projections, quaternion products, on Update?
- Is it ok to GetComponent, where T is an interface?
- Are coroutines really performant? Is there any alternatives to them? Somehow iterating over many new objects of Wait type makes me uncomfortable. I tried to yield the same object but apparently it doesn’t have the same effect. How many coroutines can I launch concurrently to except good behaviours?
- Has anyone tried to use an event-driven style within the components-driven environment of Unity? How did it work out? Isn’t it a bit of a callback hell?
- Is it ok to pass lambdas or delegates as parameters in a frequently called method like Update or FixedUpdate?
I also do a lot of caching, which is something I noticed few people do (at least in the code I saw online while searching for Unity how-tos, documentation or workarounds), but it really speeds things up, most of the time at the cost of a very tiny amount of extra memory.
So if I can give a little of advice, do not do something like object.GetComponent().something in the game loop. Especially since it can return null… you never know.
- Virtual calls are always expensive than direct calls. And you should avoid having too much Update calls. It’s better to have a manager class with one Update and call other classes’ fake update methods than having separate Update methods. Here is detailed information.
- It really depends on your usage and your platform. Extensive use of them will certainly bite, but you should experiment with it.
- It is a bit costlier than calling components, but you definitely can use it. It is funny that in earlier versions, the question was “can or can’t” rather than “ok or not”. Detailed information is here.
- There are definitely better alternatives. Check these: More Effective Coroutines | UniRx. Additionally, Coroutines only work in main thread. If you are looking for a way to use multithreading, these links may help : Threads forum discussion |
Coroutines vs. Threading.
- I’ve seen some people use events extensively, if you know your way, it will not be a callback hell. But If you ask my opinion, Don’t rely on one system. It is okay to use systems as long as they work in harmony and easily understandable. Use things that make your life easier, don’t use things that will make your life harder just because “you need to stick with it”. Perhaps this link will look familiar since you are a software engineer and can help you decide which way to go on.
- I need an example on how you are planning to use it. If you are thinking about anonymous and named methods, there is merely a performance difference.
Agreed with caching. I also see a lot of this:
transform.position = new Vector3(5,0,0);
Instead of this:
myTransform = transform;
myTransform.position = new Vector3(5,0,0);
If you use transform or gameObject in Update, it is drastically better caching reference of it. In one of my project when I was a beginner in unity, referencing myTransform boosted 10 fps performance.
Hope they can help you to make your mind a bit clearer.