Large # of gameobjects run smoothly or alternative?

I have been working on a building game project in unity, a Lego sort, and one problem that I have recently come across is size. Small numbers of these bricks go together with little lag, but then the frames drop as the brick count increases:

This image has about 1k bricks on the beautiful settings.

The bricks themselves have triggers on them that act as stud connections, and each brick has some script that handles connections and other such, all parented to an empty with a rigidbody (Set to isKinematic for now, so physics aren’t playing a role in my frames). I would really like to know if there’s a way to optimize this to allow for large scaling in the 10’s of thousands of bricks, some trick about Unity’s rendering/processing settings I don’t know about, or maybe some mesh connection?

Any help would be appreciated, even if it the answer is find another engine

Summary from comments:

  • low performance can be caused by various things, the usual cuplrits being rendering, physics, scripts, and networking

  • to find out what causes the performance issues run the profiler (Window menu → Profiler)

  • in the profiler the percentage of a row is not that important, it’s the Time column that tells you if something takes too long

  • in this case it turned out Behaviour.Update() (scripts) take 4.99ms, which is relatively a lot. Optimising scripts helped. One way to optimise scripts is to try to offload logic that doesn’t run every frame from Update() to coroutines

  • to help with rendering many similar objects - as is the case with building blocks - batching (dynamic and static) and instancing (previously called geometry instancing) can help a lot (in this case it did). Batching can be turned on in the Player settings (Editor menu → Project Settings → Player), while geometry instancing can be turned on on individual materials (for those that support it, called “Enable GPU Instancing”)

  • don’t bother with trying to manually discard sides of boxes that are not visible from your point of view, backface culling (run on the graphics card) automatically eliminates triangles whose normal faces away from the camera

  • instantiating and destroying objects a lot can also cause poor performance, because they are costly operations, and allocate and deallocate memory that the GC needs to clean up. Instead, one can try using object pooling (there are various articles on the topic on the internet)

  • to optimise physics, there are various rules. Firstly, NEVER directly modify transform.position of a game object that has a RigidBody on it, it is the most time consuming. Instead use Rigidbody.position, or even better Rigidbody.MovePosition(). Second, always apply changes to physics in FixedUpdate() (or functions called from FixedUpdate()), not from Update() or LateUpdate()

  • another physics optimisation is to approximate the collider of complex shapes with something simpler: either make the MeshCollider convex, or - if possible - use multiple primitive colliders, like Sphere- and BoxColliders

Original comment:

The issue can be graphics, physics, or the scripts. Run the profiler and check what takes so much time. In my experience 1k objects shouldn’t bring the Editor to a halt, except if they have really complicated meshes or scripts on them.

My hunch is that the issue is caused by physics, the objects continuing to collide after they get connected. Note that even if you set a rigidbody to kinematic, even though it will not move, it does take part in collisions (as far as I know).