Using OnTriggerEnter to move track. Interesting issue

Hello guys, I want someone’s input as how to make my project more efficient for mobile.

I have a track, composed in 5 lanes, each lane is divided in 26 blocks, each block has a floor, a front wall and a back wall.

So basically, the track has 5 lanes * 26 blocks per lane * 3 game objects per block to a grand total of = 390 objects, just for the track.

The reason I have divided the lanes in blocks, is so that with scaling, I can make the blocks flat (normal floor), or I can scale them up or down to grow into an obstacle or a hole. So I do need those 390 objects.

Those obstacles are generated in runtime (the scaling of the obstacles).

All those blocks are recycled, not instantiating and destroying going on. Imagine an obstacle starts is on the right side of the camera, the camera moves to the right, so the obstacle is lost to the left. On the left side there is a collider that’s a child of the camera, that triggers a function to move the block back to the right of the camera. (recycled blocks). So since it’s 5 lanes, depending on the speed, there are 5 collisions happening every second or less, and the associated code with that collision.

Is there a better way to handle this that I haven’t thought of?

The problem I’m having is that I have too many objects, too many collisions and very very occasionally (on older devices) you get small lag spikes, which take a lot off the game.

Should I have only one block collide with the camera’s collider and launch an event to tell the other blocks to move as well? would that be more efficient?

I wouldn’t use collision and triggers for that. Instead, I’d use MeshRenderer.isVisible for verifying whether an object is visible to the camera or not. If a block is not visible and it’s located at the left side of the camera, then it can be recycled.

It will be much cheaper to check that out with all your blocks than using collisions and triggers.

Thank you Edy, for your reply.

If this is indeed cheaper I will definitely make the change. I’ll update this post later on with performance results. Thanks!

UPDATE: will not work. The camera is at such a weird angle that some times, when the blocks exit the camera’s viewport, blocks sometimes skip ahead of the previous block, throwing the whole thing into an error… frustrating

UPDATE : it’s happening because the obstacles have different heigts, and some are unseen before they are supposed to be recycled… so there’s that

Well, I think it’s a kind of designing a proper logic for the recycling part. Using collisions and triggers is very expensive and I’m almost sure any other solution will be more efficient. Maybe not only isVisible, but also checking out the position of the blocks wrt the camera. It should be something specific to your project.

I have worked other projects with isVisible and with the position relative to the camera. In the case of the position relative to the camera, I always thought that that would be more expensive than collisions.

If it is indeed less expensive, I will work it in. Do you have some documentation or test where I can see that this is true?

Because the way I see it, to check a position constantly, it has to be comparing in Update against the camera’s position and making calculations. So 100+ something objects will have something running in update and taking processing power.
On the other hand, OnTriggerEnter is only calculated once per object.

Thanks a bunch

This post can be locked.

To whoever is interested, read bellow:

My game has hundreds of movable objects, many of which have colliders, all triggers. My game needs to work VERY SMOOTHLY, or the game is pointless, a single stutter can damage the experience.

So:

  1. Always cache transforms and other components you use regularly
  2. All objects will colliders have rigid bodies.
  3. Keep all objects of different types in different layers, make only the necessary layers interact
  4. When you can, use Vector3.MoveToward instead of Lerp, as lerp slows down, it takes more time to complete a movement (using up processing power)
  5. Make sure that all colliders that don’t need to interact with each other, NEVER touch each other when possible. All collisions will be checked, even if they are in different layers, something has to check that those layers don’t interact, so avoid it all together.
  6. For a smoother movement, I used smoothDelta
  7. Lock framerate
  8. Whenever you can run a method or some code, on a fixed update or coroutine that doesn’t need to be ran every single frame on Update… JUST DO IT. The less a function runs, the better
  9. Compress textures to the smallest thing that still looks good on your testing device.
  10. Compress music and sound effects. Change from Stereo to FOCE MONO
  11. Avoid collisions. There are other methods to trigger functions, isVisible for example.