OK I have a game that is similar to minecraft in a sense. Players can build castles block by block. I'm using Unity3D and Photon Network for my game and I was wondering how I would handle detecting if blocks have a support system to the ground. Here is the game in question. Let me know what are some solutions besides using rigid-bodies I've tried doing that and it has severe performance issues over a network. Thanks
Why don't you implement a child parent system? If a block is placed next to a block of the same type or a supported connecting block then add the new block as a child. That way it keeps the data from the parent block relative. You can then remove that child if say it was destroyed and add physics support so you can see what would happen to the child of the destroyed child block.
What I would do is find each of the blocks neighbors (except above). Then for each one of it's neighbors, find that blocks neighbors. Then for each of those neighbors, find the next neighbors, etc. etc. Eventually you will find all of the connected neighbors in a sort of parent-child tree like user3667971 mentioned. If any of those blocks are connected to the ground, then you have support.
Note that if you are doing this every frame, then that is pretty inefficient. I would only generate the neighbor list once for each block, and user3667971's idea of just adding it as a child to create a tree, and then find the parent of the entire tree to test for the ground.
You can do a partially update of your world. Whenever you place/remove a block from your world, check all adjacent blocks.
If you place a block
A ontop of Block
B, then you check all sides around
A. If any block (for example
B) is directly below, one to the side and below or directly adjacent (if you want to support that), then place the block and it will rest. If no support is there, it will start to fall.
Checks required in pseudocode (No direct side-support, you'll figure it) function blockPhysics() List<Block> toUpdate = new List<Block>(); boolean isFalling = true; foreach( Block B near A ) //which is not falling at the moment if (A.y-1 == B.y && Math.abs(A.x - B.x) <= 1) //have block stay at position isFalling = false; else //remember B so we can tell him we are gone toUpdate.add( B ); end end if( isFalling ) //trigger our fall and handle it FIRST! fallDown(); //Your job to implement. You probably simply want to set a flag named canSupportOtherBlocks. //Then have every surrounding block do his own physic calculations. foreach( Block B in toUpdate ) B.blockPhysics(); end end end
If you remove a block
B from below Block
A, then you trigger the blockPhysics from all surrounding blocks.
function remove() //we have to remove B first, otherwise this would disturb the Physics removeSelf(); foreach ( Block A near B ) A.blockPhysics(); end end
This will trigger any block
B to check again it's support. This will possibly trigger a cascade of blocks falling. But what else do you expect if you build a reverse pyramid and remove the support.