0
\$\begingroup\$

Does a C# script added to a parent object work more efficiently and effectively (in terms of both memory and performance) on all objects, in my case lighting, or adding script components to each lighting/GameObject object? This goes for other GameObjects parented in the hierarchy.

\$\endgroup\$
3
\$\begingroup\$

There is some amount of overhead to invoking each script's Update() and other methods, compared to maintaining a list of objects and updating them all at once from a single entry point.

So, if you maintain a list of multiple objects to update, you may see some runtime efficiency wins by iterating over them from within a single script instance. Just note that if you're searching for instances to update using FindObjectsOfType or GetComponentsInChildren, the search cost will likely outweigh the savings of not invoking each one's Update separately. So look for ways that you can persist the list across frames rather than re-building it continuously.

In practice, I haven't experienced noticeable slowdowns from having dozens and dozens of instances of simple scripts updating independently, so I recommend profiling first before adding complexity to your project - it may be premature optimization for many applications.

You should also weigh whether your developers may gain iteration efficiency by keeping the instances separate. This can make it easier to individually select & tweak a single instance or group of instances, or make use of prefabs and object references. These operations can get more complicated if the needed methods & data are tied up in a higher-level manager script.

Which pattern makes more sense for a particular feature will depend a lot on the specifics of what you're trying to accomplish, what workflows your team likes to use, and what your performance profiling looks like.

\$\endgroup\$
0
\$\begingroup\$

Well, the stuff that are exampled may or may not be benefits depending on what people like doing but there are some definite benefits in my opinion.

For example, I could have as much as 50 (maybe more) planet game objects in my game. They all had attractors attached to them (this didn't occur to me as a problem at first) and I wanted them to turn around themselves slowly.

At first I had attractors and the picture of the planet on the same game object and I noticed a significant increase in CPU usage when there were too many planets. After investigating the issue further, I found out that the physics calculations were taking an immense amount of time every frame. It then occurred to me that, turning attractors and rigid bodies every frame could be the culprit.

I've removed the planet picture from the game object prefab then I made a child object which had only the picture. There it was, I was no longer turning physics objects for a simple turn animation. Suddenly, physics calculations were down to just about 1% - 0% per frame from a whopping 80% on levels with many planets.

So, yeah, there are benefits to having a container object for all your other objects, but the implementation is what really matters. Nothing is ever a "fit all and do all" kind of solution.

In your case, there might not be any improvement from iterating over every single light in a parent script to putting scripts on each light. As far as I know, Unity will use separate threads for separate objects in game. The single container object with a single script will not be automatically threaded, so you will need some effort on your part to properly thread that one.

\$\endgroup\$
  • 2
    \$\begingroup\$ As far as I know, Unity never multithreads script code (unless you explicitly create threads, of course). This is convenient for the developer because it means you don't need to be afraid of unexpected thread interactions when multiple scripts affect the same game object. \$\endgroup\$ – Philipp Jan 20 '18 at 0:30
  • \$\begingroup\$ @Philipp Yeah, it may be so, I don't actually have any test results, but I'll look into this once I have access to my setup (probably in 40 hrs or so) and update the answer with actual findings. \$\endgroup\$ – John Hamilton Jan 20 '18 at 5:16
  • 1
    \$\begingroup\$ Unity is (by default) single threaded: all Update() methods in all MonoBehaviour scripts are on the same thread (this is why the Script Execution Order setting exists). There are ways to create child threads, but Unity doesn't always play nice. Coroutines look like threads, but aren't (they're a managed schedule system that runs on the main thread). \$\endgroup\$ – Draco18s Jan 20 '18 at 23:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.