- Home /
Demolishable object that won't kill my framerate
I have a voxel-based object that moves around my world. Right now I have it so that the object is made up of many separate cube objects parented to the main object. Each of these separate cubes has a script attached that makes it so they unparent when hit by a projectile and thus the object is completely destructible.
The problem is, the main object is then made up of about 900 separate cubes, and all of them, even the inner ones are always loaded.
I've tried InstantOC, an occlusion culling system, but even at a high raycast sample rate (which gets to be similarly expensive on it's own), the cubes don't always render properly, especially at semi-far distances.
I really need my object to be completely destructible as it is with just as many individual objects, but this is a major roadblock as I need to have many of these objects on screen at once eventually, so this needs to be solved before I move on.
If you could offer any help or suggestions, I would greatly appreciate it, thanks!
So, I was thinking that I could set up a parenting system for the entire object where each cube would have a script that would enable the inner objects touching it when it gets knocked off, but there must be a better way.
Another thought is that I could do the object in shells, with the outer shell always visible, and then the inner ones done with occlusion culling. And then once enough pieces fall off the outer shell, the nextmost inner one completely renders regardless of occlusion culling, and so on to the innermost shell.
Well the "easiest" way is not to use separate game objects/meshes and to create a data structure that models your cube and then when you need to divide it (or whatever) you modify the mesh associated with the cube. Using a subdivision system (which would be non-trivial to write) you could have it so that the original mesh is just 24 vertices and then as you hit blocks you would alter the mesh. That said you would benefit from some culling if you made it from sections and then applied that process to those.
That sounds interesting. Is there any example of an implementation of that that you could refer me to?
They turn them into multiple mesh combinations like I'm suggesting, allowing the GPU to do the heavy lifting and the "simple" voxel model to be represented by a suitably compact data structure.
A simple cube made up of 1000s of other cubes can be rendered as a single 6 faced cube when complete, each removal of a block can complicate it, but perhaps not too much in truth. Using GameObjects is going to force an almighty amount of culling and overdrawing that is unnecessary.
Answer by Zarenityx · Jul 09, 2013 at 01:56 PM
You have fallen into the biggest and most fallen into trap in the world of voxel-making. Voxels aren't actually cubes. If they were, then even a very small world, say 10x10x10 blocks would be 1000 cubes, which means 12000 triangles and 24000 vertices. Voxel engines actually use 'hypothetical voxels', which contain all of the information you might need to construct a voxel (uv coords, light, light emission, solidity, transparency...). Everything except a transform(because this is dependent on their location within the chunk. Then you need to make chunks(these can be objects), with a script that both stores a 3d array of hypotheticals, and then uses them to proceduraly generate a mesh for the chunk that only shows the faces which would be visible.
Essentially: Take this voxel. If it is solid, then proceed, otherwise skip it and move on. If there is a transparent voxel on this side, build a side of the cube, otherwise skip that side and go on.(do this for all of the sides) Then move on to the next voxel...
REMEMBER! YOU NEED AIR VOXELS! (non-solid, transparent voxels).
VOXEL GENERATION CAN BE VERY EASY, BUT REMEMBER: VOXELS ARE NOT OBJECTS I hope this helped. I am working on a voxel engine as well, and once I learned about this, My month long brain-ache finally stopped.
Awesome! This makes sense, thank you. Now to figure out how to implement this... Does this mean I can't use qubicle to create my models?
I am not sure about all the details of Qubicle, having never actually used it, but to do the hypothetical voxel thing, your mesh needs to be procedurally generated. Essentially the voxels themselves don't have models, they map the model of the chunk. If you want fancy looking voxels, you may want to add a smoothing algorithm or something, otherwise it means long, tedious hours of procedural mesh coding. You could use Qubicle for the models of your mobs and stuff, but not for the actual voxels. As I understand it, Qubicle itself is a voxel engine, which contains only one chunk, then exports the model of the chunk that you edited. And if you want the objects to be destructible, this won't work. Sorry.
Also, I forgot to mention a few simple things that really gave me brain-aches before I figured them out-
Each chunk must be re-rendered every time a voxel is added/removed
You need to overload all the arrays, otherwise you will get a ton of out of range errors
Handle generation by the world, but rendering by the chunks.
Ah, so essentially I'll be generating my terrain procedurally with the method that you're describing, and all my models with Qubicle.
Even though it doesn't really relate to the destructible object problem I was facing, this is still great information for when I begin generating large chunks of terrain! Thanks :)
Answer by aldonaletto · Jun 18, 2013 at 04:51 PM
I would try a different approach: child the cubes to the healthy object and keep them deactivated - this way the cubes aren't rendered and don't waste time with physics calculations. When needed, detach and activate the children and destroy the healthy object.
The hierarchy could be something like this:
HealthyObject // the healthy version, is active from the beginning
DestroyedVersion // damaged version - empty object deactivated from the beginning
Cube // object pieces, all of them childed to the empty DestroyedObject
Cube // the pieces are set active by default, but will stay deactivated
Cube // because their parent isn't active
...
When the object is hit, set DestroyedVersion.transform.parent to null in order to detach it and destroy or deactivate HealthyObject: all pieces below DestroyedVersion in the hierarchy will wake up, since they already were active (although kept inactive due to their parent being deactivated).
If I understand properly what you are saying here, all of the cubes would then fall off after the healthy object is hit. The problem with that is that I need all of the cubes as independent pieces who each react to being hit separately. I don't know if I'm explaining this well. Basically if I still wanted to achieve what I'm trying to achieve using this, the hierarchy would be like this:
Healthy Object
DestroyedVersion
Cube
Healthy Object
DestroyedVersion
Cube
//Etc. for each individual cube
which wouldn't save me any.
I thought you wanted to make the object completely explode into pieces when hit. If the object must be destroyed partially according to the impact, this approach just makes things worse. $$anonymous$$aybe you could keep the inner cubes deactivated, but this would require a smart code to decide which cubes are exposed, and activate them.
Yeah I know, which is exactly the kind of code I want to avoid writing haha...
$$anonymous$$aybe this could be implemented with a tridimensional GameObject array containing references to the cubes according to their positions. The script should activate the objects that have at least one neighbor empty (in six directions - corners don't count), and a detached cube should store null in its array position, so that the exposed neighbours could be activated by the control script.
Yes, that's the sort of thing I need to code. However, a couple of things first that might complicate it a little. The main object is made up of cubes, but isn't a cube itself. So the main object is irregularly shaped. Also, to avoid even more cubes, some of the pieces that need to fall off are made up of a few cubes (think tetris shapes). Also, the inside of the main object has some hollow areas.
Answer by predatordpc · Jun 18, 2013 at 04:52 PM
maybe make particle system with those cubes as an particles, and when object gets hit maybe change it to other model (maybe 1 block? or replace with explosion ), then some script enabling particle system shoting cubes in all directions
Thanks for the suggestion, but I don't think that will work for what I'm going for.