How many (MonoBehaviour) scripts are considered too many?

Hey there, during prototyping phase in game development, I ended up using a single script for many objects in a scene (containing one to two variables). For example, each ammo stash collectible is required to have a variable of different value, hence the “AmmoValue” script in each object.

Does having more than 100 of those objects in a scene make performance suffer?
If yes, what could possibly be a workaround method to store and edit values for these types of objects that require a different number each one, even without a monobehaviour script?

1 Like

No, I have over 10,000 ‘objects’ (according to the unity profiler) in my mobile game, runs at 60 fps on most devices ~2 years old or newer, 30 fps on 5 years old and newer devices.

Objects existing are almost free, the only performance that might suffer is if you have to run updates on all those objects but it sounds like you don’t, or if they are all dynamic physics objects, or have high rendering costs.

In general you shouldn’t worry too much about performance until it becomes an issue, then when it does, profile it and you’ll usually find the things that are slow are things you never would have guessed are slow.

1 Like

What @Antony-Blackett said.
Although it’s beneficial to start with object pooling from the start. It will be less painful to rewrite half of your application for it. And you almost certainly will need it. But other than that, just be mindful and try to make everything you designed on the least possible way.

There are also other techniques which reduce the risk of performance issues (like custom update loops), but I think you’re a very beginner, so it’s okay to learn it later, when you actually have performance issues.

1 Like

Well the reason I care about performance early on is so that I don’t change my methods mid-development.

The objects don’t use updates indeed, and I really can’t pool those, as I specifically edit the values to be different for each one. So, none really are alike. I use pooling for bullets and such, objects whose values are identical.

What worries me is the garbage collector after they are getting Destroyed once collected and their population. But since you guys have 10000+ monobehaviours, I guess then the performance is cool for now…

1 Like

These two aren’t related. If you have two of the same type but different values, you still can pool it. You just initialize from a database or something. Like you’re pooling bullets and then update the initial position to the current position and rotation of the gun.

Sure thing. Besides all that, I’m still trying to figure out some trickery to manipulate a large number of objects with different/identical values. The entity component system is similar to what I have in mind, but it is kinda complex, at least for me.

A common case to use this system for would be NPCs. The same behaviour controlled by one master/brain script, applied to an X number of NPCs, but still storing different data for each one (position, rotation, health etc). A complex matter to solve…

As lurking said, look to object pooling. 100 units in a scene each with 20 components attached is not crazy, but constantly creating and destroying them can be expensive and trigger a lot of garbage collection which can impact performance.

2,147,483,647 is starting to get too many. You’ll start running into problems with 32 bit systems running out of address space.

As long as you stay clear of that, you’ll be fine.

:stuck_out_tongue:

(The real answer is use exactly as many as it takes to get the job done.)

2 Likes

Also, always keep an eye on profiler.
If you implement something new, check for its performance.
Is easier to track issues early.

I personally trying keep to minimum MonoBehaviours. Close to 1.

@Kiwasi That’s my answer right there! :'D
@Antypodish What do you mean keep MonoBehaviours close to 1? Only 1 MonoBehaviour in your whole project?

Having monos without Update or trigger methods isn’t that expensive. Having a few hundred with Updates is ok too. But I would try to disable objects thats not relevant etc so they are not updated unnecessary. Though, don’t do premature optimization. Instead write maintainable code that is agile and easy to refactor and reshape when you do need to optimize

Yes.

Must be very simple projects then.

Yes it is, look my signature.

Not necessarily. Its possible to move all of the code out into vanilla C# and just have one MonoBehaviour to trigger it all. Its a common strategy for some types of games.

1 Like

How do you work with collision in those games? Collision in unity needs a monobehaviour with OnCollsion declared, etc

What if the game doesn’t need collision?

Or maybe the game has very simple collision that doesn’t require box2d or physx.

I worked on a simple old-school strategy game recently. The game itself was completely independent of Unity, and already was running on mobile and in a simple debugger tool. They just wanted Unity to be a flashy/pretty visual layer over the game itself.

2 Likes

There is numerous ways. For example from simple use of raycast, to use of trees, like octree for example, calculate own AABB and OBB, or other spatial method. I.e.

https://www.youtube.com/watch?v=GEuT5-oCu_I

As @Kiwasi mentioned, I can scale to whatever number of objects I want, with use of single MonoBehaviour.
Very helpful approach, when working with ECS.

1 Like

Thats ECS and C# Jobs, I talk about classic Monobehaviours. If you want to subcribe to collision each rigidbody needs its monobehaviour

You can cast a ray from simple C#. It’s not have to be ECS or job. It’s not mandatory to subscribe to collisions you can detect the same effect with other tools.