- Home /
Why is my script causing Unity to crash?
I am working on a voxel role-playing game, and I wrote a script to randomly generate a world. I will put the script at the bottom. I created a prefab for the voxel, and it is just a cube with nothing attached to it. Now, when I attach the script to an empty GameObject, and hit play, Unity hangs forever until you end the process with Task Manager. There does not appear to be a memory leak in my code. Why is this happening?
using UnityEngine;
using System.Collections;
public class WorldGenerator : MonoBehaviour
{
public System.Random rand;
public int WORLD_HEIGHT = 64;
public int WORLD_LENGTH = 64;
private double CUBE_SIDE = 0.5;
private float[,] grid;
private int[, ,] blocks;
public float roughness = 0.1f;
public Transform Cube;
// Use this for initialization
void Start()
{
rand = new System.Random();
int xh = WORLD_LENGTH - 1;
int yh = WORLD_LENGTH - 1;
grid = new float[WORLD_LENGTH, WORLD_LENGTH];
grid[0, 0] = (float)rand.NextDouble() - 0.5f;
grid[0, yh] = (float)rand.NextDouble() - 0.5f;
grid[xh, 0] = (float)rand.NextDouble() - 0.5f;
grid[xh, yh] = (float)rand.NextDouble() - 0.5f;
Gen(0, 0, xh, yh);
blocks = new int[WORLD_LENGTH, WORLD_HEIGHT, WORLD_LENGTH];
for (int x = 0; x < WORLD_LENGTH; x++)
{
for (int z = 0; z < WORLD_LENGTH; z++)
{
int height = (int)System.Math.Floor((double)(grid[x, z] * WORLD_HEIGHT));
for (int y = 0; y < WORLD_HEIGHT; y++)
{
if (y <= height)
{
blocks[x, y, z] = 1;
Vector3 blockpos = new Vector3((float)(x * CUBE_SIDE), (float)(y * CUBE_SIDE), (float)(z * CUBE_SIDE));
Instantiate(Cube, blockpos, Quaternion.identity);
}
else
{
blocks[x, y, z] = 0;
}
}
}
}
}
private void Gen(int xl, int yl, int xh, int yh)
{
int xm = (xl + xh) / 2;
int ym = (yl + yh) / 2;
if ((xl == xm) && (yl == ym)) return;
grid[xm, yl] = 0.5f * (grid[xl, yl] + grid[xh, yl]);
grid[xm, yh] = 0.5f * (grid[xl, yh] + grid[xh, yh]);
grid[xl, ym] = 0.5f * (grid[xl, yl] + grid[xl, yh]);
grid[xh, ym] = 0.5f * (grid[xh, yl] + grid[xh, yh]);
float v = Roughen(0.5f * (grid[xm, yl] + grid[xm, yh]), xl + yl, yh + xh);
grid[xm, ym] = v;
grid[xm, yl] = Roughen(grid[xm, yl], xl, xh);
grid[xm, yh] = Roughen(grid[xm, yh], xl, xh);
grid[xl, ym] = Roughen(grid[xl, ym], yl, yh);
grid[xh, ym] = Roughen(grid[xh, ym], yl, xh);
Gen(xl, yl, xm, ym);
Gen(xm, yl, xh, ym);
Gen(xl, ym, xm, yh);
Gen(xm, ym, xh, yh);
}
private float Roughen(float v, int l, int h)
{
return v + roughness * (float)(rand.NextDouble() * (h - l));
}
}
Well, 64*64*64 is (2^6)^3 = 2^18 =~ a quarter of a million. It may just be taking a long time. Try it with WORLD=4? And some Debugs, just to be sure z isn't stuck at 0 or something?
Also keep in $$anonymous$$d that each recursive function call needs a stackframe and your local variables needs 28 bytes. So each call will consume quite a bit of memory. Also function calls are quite slow when calling them that much.
You can't make a 'voxel' game by instantiating cubes in a 3d grid. Can't. So stop trying, and read up on the right way to do it before starting over.
Also, as a general rule, solitary noob open-world-RPG-as-first-game-design projects almost never result in anything worthwhile. If you want to finish a game, start smaller.
Answer by HappyMoo · Dec 31, 2013 at 04:49 PM
Calling instantiate 260k times won't scale, also you'll have cube faces generated that you actually don't need.. the faces touching each others etc.
I recommend you have chunks and generate all the geometry per chunk yourself in the meshfilter.
Here's an example how to do it: http://www.youtube.com/watch?v=_3ZODVA0yKQ
Yeah, this. If $$anonymous$$inecraft worked that way, it would have over a million times as many gameObjects than there are grains of sand on planet Earth.
Proof this works: http://pbs.twimg.com/media/BZrfeqHCQAE4e8r.jpg:large
Your answer
Follow this Question
Related Questions
World Seed 2 Answers
Generating 2D voxel circles using a noise function 0 Answers
Noise block terrain generation? 0 Answers
Using noise to generate Cube World like terrain 0 Answers
Character customization in-game 0 Answers