- Home /
Why does setting the Camera Clip Plane make my game run slow?
A little background: I am making a game similar to Minecraft with a three-dimensional array of cubes. This array is a 50 x 50 x 10 and whenever I turn Camera Clip Plane to only show cubes close to the player, the game tends to lag a lot. I have made one solution, but every 10 seconds, a very large lag occurs, but the game otherwise runs smooth. This was my fix:
IEnumerator setVisibleRange(List<List<List<GameObject>>> blockList) {
canScanRange = false;
for(int r = 0; r < blockList.Count; r++) {
for(int c = 0; c < blockList[r].Count; c++) {
for(int d = 0; d < blockList[r][c].Count; d++) {
if(blockList[r][c][d] is GameObject) {
float dist = Vector3.Distance(blockList[r][c][d].transform.position, GameObject.Find("Player").transform.position);
if(dist > 50) {
blockList[r][c][d].SetActive(false);
} else {
blockList[r][c][d].SetActive(true);
}
}
}
}
}
yield return new WaitForSeconds(10);
canScanRange = true;
}
My 'fix' has to run though EVERY element in the array which makes the lag happen. Is there a way for this lag to go away?
You can't make a game like $$anonymous$$inecraft using a 3-dimensional array of cubes, at least not one that will run smoothly on currently available hardware. You're simply doing it wrong and no amount of optimizing will help. If you want to make a voxel based game, read up on how voxel engines work first.
Just for fun, edit your script to make the array 64,000,000 x 64,000,000 x 256 and see what happens.
Answer by Eric5h5 · Dec 17, 2013 at 04:47 AM
50x50x10 is 25,000 objects, which is way too many. Even if they aren't all drawn (which is 25,000 draw calls), they all have to be culled every frame. You can find lots of answers about minecraft stuff in Unity with a search, and they will all tell you to write code that creates mesh chunks, rather than instantiating each cube as a separate GameObject. Creating mesh chunks will increase efficiency by orders of magnitude and you can ditch the SetVisibleRange function.
Answer by Spinnernicholas · Dec 17, 2013 at 04:03 AM
First off, Vector3.Distance is very, very slow because of the square root involved. Use Vector3.sqrMagnitude and compare it to 50*50. That should have an immediate effect.
Not true; CPUs have evolved since the '90s when square roots actually were slow. On any semi-modern desktop CPU (and including some AR$$anonymous$$ chips), square roots are a hardware instruction and you can do tens of millions of them per second. ($$anonymous$$ine will do nearly 100 million per second in Unity, but some of that is really the function call overhead rather than the actual square root operation.) In most cases you won't see any difference between .magnitude and .sqr$$anonymous$$agnitude unless you're doing huge amounts of them. (Although there are huge amounts in this case.)
Also, don't bother trying to avoid division, it's just as fast as addition and subtraction these days....
That helped reduce the lag by A LOT. Thank you so much!
Is there a way to set all the non-rendered objects (using camera clipping plane) to inactive?
if ( !its.renderer.isVisible ) { its.gameObject.SetActive (false); }
But this whole approach is still a lost cause; you should mark Eric's answer correct and do some more research before starting over rather than putting more time into it.
Answer by 13dnizinski · Dec 17, 2013 at 04:22 PM
Okay - I found an answer: If I parent a bunch of objects to a 'chunk' gameobject, Instead of iterating though all the blocks, I would only have to set specific chunks visible, which in turn would set all their children blocks to visible.
Your answer
Follow this Question
Related Questions
Reduce water's reflection camera max clipping plane 1 Answer
GUI on one camera visible to other camera 1 Answer
Problem with 3D objects rendering in front of closer objects. 1 Answer
Oblique Frustum Clipping 0 Answers
Shadow flicker 0 Answers