I’m implementing a game with an endless level, where blocks get reused. These blocks have colliders on them, the only rigidbody is the player object.
here is a screenshot to show you the situation:
Since the blocks get reused, i deactivate them if they get out of screen, move them to the right when needed and reactivate them. since these are static colliders i pay the performance penalty for moving a static collider.
I’ve tried applying a kinematic rigidbody to each of those, but than physics takes up quite some time, because it simulates ALL rigidbodies (the profiler lists them).
Is there a way to tell unity to not simulate the kinematic rigidbodies and use them for collision with the non-kinematic player only? or do i have to either pay the penalty for a lot of rigidbodies or moving static collision?
what i’m about to say sucks, and i wish there was a better way to avoid the penalty or i knew it anyways, but use prefabs or gameobject offscreen configured how you would like.
Use instantiate with the position and rotation overload to make the instances.
This really is only beneficial if your game objects your instantiating are not super complex with a lot of children. Use mesh combiner when you can. But you’ll notice in the profiler if you instantiate either a gameobject in your scene or a prefab which has a ‘static’ collider you wont get as big as a penalty. If you cahnge the transform at all after the instantiate you will get the penalty ( even changing parent ).
So again if your game objects are fairly simple this should be a good way to accomplish waht you need without using rigidbodies at all. Just make sure to call destroy once unused things are offscreen. I’m fairly confident given simple objects this way is faster than trying to reuse a single static collider multiple times.
With any solution you should make sure that your putting out more colliders infront of the player ( assuming the players only going one direction ) and then have some slow thinking coroutine which checks when previously made colliders are off screen maybe 3 or 4 times a second depending on how fast the game is and then instantiates ahead blocks.
Just my two cents though, I’ve found deactivating and reactivating game objects has penalties as well which as long as your throttling the instantiations so it doesnt isntantiate more than a couple of things per frame only when it needs to you’ll keep the framerate playable and avoid alot of penalties.
I really wish there was a way to pause the awake of the colliders from a instantiation to where it wouldn’t penalize you so you could change parenting or even localscale, ect…
@ivkoni: i’ve tried the layer based collision already. The Level-Block Rigidbodies are on the Default layer then, the player on the Player layer. Disabling the Default<—>Default layer collision allows me to have the player collide with the level only, not the level parts itself. Still it seems that the penalty for having all the rigidbodies (event if they are not colliding) is quite high.
@BDev: Instantiating and destroying objects is better than reusing them? The instantiate/destroy does quite some memory allocation and garbage collection afterwards. Are you sure that the penalty for that is lower then reusing the levelparts with their colliders? I only set the position of the collider when reactivating them.
Anything that extends UnityEngine.Object in unity is not garbage collected. While there is a little bit of garbage collection going on from tasks like instantiate, it should be minimal.
Theres no way to actually not trigger a garbage collect because of GUI and some other things, so its kind of fruitless to worry about as long as you can avoid situations where you release a bunch of references ( like hundreds ) at once causing the garbage collector to go crazy.
The project i’ve been working on has seeded level generation and i’ve definitely found that instantiation is faster than reusing static colliders. Like i mentioned it depends on the complexity of what your instantiating ( like one collider, one renderer with mesh and a user script works fine for me ). As long as you generate objects, check for them needing to be destroyed in a slow running coroutine you’ll be ok on GC.
thx for the answer. My gameobjects are rather small too, just a quad as mesh, texture and a script (+ the Collision Object)
I’ll try out your suggestion as soon as possible.
Are you sure physics are a performance bottleneck?
Reusing stuff like you’re doing should work just fine. Moving them around should be cheap, not even a need to deactivate them if there are only a few. Though perhaps you shouldn’t mark them as static, don’t know about that. Also, the blocks needn’t be ridigbodies if they’re just sitting there, having colliders is enough.
I have a game that’s full of rigidbodies that I reuse and switch on and off all the time. Somewhere between 100 and 200 of them. It runs fine on a 1st generation iPod Touch. I’m also writing a tutorial right now that basically does the same as your game, though admittedly a tutorial is a far cry from a true game.
Hi Jasper,
thanks for your answer. In the profiler i can see, that physics takes up quite a considerable amount of time. I didn’t mark any of the colliders as static, just added colliders to my game objects. still i can see the “collider moved performance penalty” msg in the profiler. I’m sure that my gui takes up quite a lot of performance as well and seems to provide peaks caused by the garbage collector. I’m trying to get rid of that too at the moment.
I’ve got about 20-30 colliders (only box) in the scene, with the ball as rigidbody at the moment. I don’t see any drops when using the web player, but it’s showing on the android devices i tested.
You’re using the profiler with those android devices? Sadly I have zero experience with those, but enough with iOS to know that the problem can end up being something entirely different.
i’m using the profiler on pc, which shows me the hickups too. I don’t really know how to profile on android, but hoped that the issues might be caused by the same source