- Home /
Question by
awplays49 · Jul 04, 2015 at 05:07 PM ·
2dprogrammingsidescrollersandbox
How to edit the following code to make world chunks disappear when past render distance?
Hi, I have a generation system where the following happens in order:
-The world is determined.
-The world generates visually in chunks based on if the player is near the chunk.
-The world never deactivates and causes lag.
Just taking a look at the Update method and the last 2 methods is all I'm asking:
using UnityEngine;
using System;
using System.Collections;
public class TerrainGeneration : MonoBehaviour {
public int width, height;
[Range (0, 100)]
public int fillPercent;
private enum Cubes
{
No,
Yes
};
private Cubes [,] map;
private enum CubeTypes
{
Dirt,
Grass,
Cobblestone,
DirtMoss,
CobblestoneMoss
};
private CubeTypes [,] mapData;
private enum CubeRounding
{
BottomLeft,
BottomMiddle,
BottomRight,
MiddleLeft,
Middle,
MiddleRight,
TopLeft,
TopMiddle,
TopRight,
Bottom,
Left,
Right,
Top,
LeftRight,
TopBottom,
Single
};
private CubeRounding [,] roundingData;
public string seed;
public bool useRandomSeed;
public int smoothness;
public int edgeThickness;
public GameObject player;
public int chunkSize;
public int leftmostChunk, rightmostChunk;
public int hillStrength;
public int hillHeight;
public int hillSample;
public int mossLevel;
public int cobblestoneLevel;
public GameObject chunkContainer;
public int renderDistance;
public int deactivationDistance;
public GameObject [] dirt;
public GameObject [] grass;
public GameObject [] cobblestone;
public GameObject moss;
public int cobblestoneIncrease;
public int cobblestoneIncreaseDistance;
public int leftRender;
public int rightRender;
public GameObject [] chunks;
// This constructor checks blocks around the block being plugged in at x, y
int GetNeighbors (int x, int y) {
int neighbors = 0;
for (int x2 = x - 1; x2 < x + 2; x2 ++)
{
for (int y2 = y - 1; y2 < y + 2; y2 ++)
{
if (x2 != x || y2 != y)
{
if (x2 > -1 && x2 < width && y2 > -1 && y2 < height + hillHeight)
{
if (map [x2, y2] == Cubes.Yes)
{
neighbors ++;
}
}
}
}
}
return neighbors;
}
// This constructor checks above the block until going up h times
bool CheckAboveBlock (int x, int y, int h) {
if (height + hillHeight - y > h)
{
for (int y2 = y + 1; y2 < y + h + 1; y2 ++)
{
if (map [x, y2] == Cubes.Yes)
{
return true;
}
}
}
else
{
for (int y2 = y + 1; y2 < height + hillHeight; y2 ++)
{
if (map [x, y2] == Cubes.Yes)
{
return true;
}
}
}
return false;
}
CubeRounding RoundBlock (int x, int y) {
if (y > 0)
{
switch (map [x, y - 1])
{
case Cubes.Yes:
if (x > 0)
{
switch (map [x - 1, y])
{
case Cubes.Yes:
if (x < width - 1)
{
switch (map [x + 1, y])
{
case Cubes.Yes:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.Middle;
case Cubes.No:
return CubeRounding.TopMiddle;
}
break;
}
break;
case Cubes.No:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.MiddleRight;
case Cubes.No:
return CubeRounding.TopRight;
}
break;
}
break;
}
break;
}
break;
case Cubes.No:
if (x < width - 1)
{
switch (map [x + 1, y])
{
case Cubes.Yes:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.MiddleLeft;
case Cubes.No:
return CubeRounding.TopLeft;
}
break;
}
break;
case Cubes.No:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.LeftRight;
case Cubes.No:
return CubeRounding.Top;
}
break;
}
break;
}
break;
}
break;
}
break;
}
break;
case Cubes.No:
if (x > 0)
{
switch (map [x - 1, y])
{
case Cubes.Yes:
if (x < width - 1)
{
switch (map [x + 1, y])
{
case Cubes.Yes:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.BottomMiddle;
case Cubes.No:
return CubeRounding.TopBottom;
}
break;
}
break;
case Cubes.No:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.BottomRight;
case Cubes.No:
return CubeRounding.Right;
}
break;
}
break;
}
break;
}
break;
case Cubes.No:
if (x < width - 1)
{
switch (map [x + 1, y])
{
case Cubes.Yes:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.BottomLeft;
case Cubes.No:
return CubeRounding.Left;
}
break;
}
break;
case Cubes.No:
if (y < height + hillHeight - 1)
{
switch (map [x, y + 1])
{
case Cubes.Yes:
return CubeRounding.Bottom;
case Cubes.No:
return CubeRounding.Single;
}
break;
}
break;
}
break;
}
break;
}
break;
}
break;
}
}
return CubeRounding.Middle;
}
void Start () {
CreateGrid ();
}
void Update () {
// This makes sure all the current rendering is done in one frame
for (int i = 0; i < renderDistance; i ++)
{
// If the player is beyond a certain distance and the whole map hasn't been renderered on that side
if (player.transform.position.x < -leftmostChunk * chunkSize / 4 + chunkSize / 4 * renderDistance)
{
if (leftmostChunk * chunkSize <= width / 2 - chunkSize)
{
CreateCubes (-1);
}
}
if (player.transform.position.x > rightmostChunk * chunkSize / 4 - chunkSize / 4 * renderDistance)
{
if (rightmostChunk * chunkSize <= width / 2 - chunkSize)
{
CreateCubes (1);
}
}
}
if (player.transform.position.x < -leftRender * chunkSize / 4 + chunkSize / 4 * renderDistance)
{
RenderCubes (width / 2 / chunkSize - leftRender - 1);
}
if (player.transform.position.x > rightRender * chunkSize / 4 - chunkSize / 4 * renderDistance)
{
RenderCubes (width / 2 / chunkSize + rightRender + 1);
}
}
// Creates arrays to contain block data
void CreateGrid () {
map = new Cubes [width, height + hillHeight];
mapData = new CubeTypes [width, height + hillHeight];
roundingData = new CubeRounding [width, height + hillHeight];
chunks = new GameObject [width / chunkSize];
Randomize ();
}
// Based on a seed, this places blocks and empty spaces based on chance of fill percentage and edge thickness
void Randomize () {
if (useRandomSeed == true)
{
seed = Time.time.ToString ();
}
System.Random prng = new System.Random (seed.GetHashCode());
for (int x = 0; x < width; x ++)
{
for (int y = 0; y < height; y ++)
{
if (x < edgeThickness || x > width - edgeThickness - 1 || y < edgeThickness)
{
map [x, y] = Cubes.Yes;
}
else if (prng.Next (0, 100) < fillPercent)
{
map [x, y] = Cubes.Yes;
}
}
}
// Hills are pulled out of the ground s amount of times
for (int s = 0; s < hillStrength; s ++)
{
int additiveHeight = prng.Next (hillSample, hillSample + 2);
int newHeight = height + additiveHeight;
BuildHills (newHeight);
}
// Smoothing occurs s2 amount of times to give more public flexibility
for (int s2 = 0; s2 < smoothness; s2 ++)
{
SmoothMap ();
}
DetermineCubes ();
CreateCubes (-1);
CreateCubes (1);
}
// If a block has mroe than 4 neighbors, it becomes a definite cube. If it has exactly 4, it is left alone. Less than 4, it is destroyed.
void SmoothMap () {
for (int x = 0; x < width; x ++)
{
for (int y = 0; y < height + hillHeight; y ++)
{
int neighbors = GetNeighbors (x, y);
if (neighbors > 4)
{
map [x, y] = Cubes.Yes;
}
else if (neighbors < 4)
{
map [x, y] = Cubes.No;
}
}
}
}
// This places some blocks above the ground that are later smoothed out. This is just an early implementation that will be changed later
void BuildHills (int n) {
System.Random prng = new System.Random (seed.GetHashCode ());
for (int x = 0; x < width; x ++)
{
if (map [x, height - 1] == Cubes.Yes)
{
if (prng.Next (1, 4) == 1)
{
for (int y = height - 1; y < height + hillHeight; y ++)
{
if (y < n)
{
map [x, y] = Cubes.Yes;
}
}
}
}
}
for (int x = 0; x < width; x ++)
{
for (int y = height - 1; y < height + hillHeight; y ++)
{
int neighbors = GetNeighbors (x, y);
if (neighbors == 0)
{
map [x, y] = Cubes.No;
}
}
}
}
// Based on the environment and circumstances of each cube, each space is put into an array of enums that says what each block is
void DetermineCubes () {
System.Random prng = new System.Random (seed.GetHashCode ());
for (int x = 0; x < width; x ++)
{
for (int y = 0; y < height + hillHeight; y ++)
{
int neighbors = GetNeighbors (x, y);
if (neighbors >= 6 || y == 0)
{
int section = 0;
for (int s = 0; s < (height + hillHeight) / cobblestoneIncreaseDistance; s ++)
{
if (s < y / cobblestoneIncreaseDistance && s >= y / cobblestoneIncreaseDistance - cobblestoneIncreaseDistance)
{
section = s;
break;
}
}
if (y < height && prng.Next (0, 100) > cobblestoneIncrease * section)
{
mapData [x, y] = CubeTypes.Cobblestone;
}
}
else if (y < height + hillHeight - cobblestoneLevel && prng.Next (1, 4) == 1)
{
mapData [x, y] = CubeTypes.Cobblestone;
}
if (mapData [x, y] == CubeTypes.Dirt)
{
roundingData [x, y] = RoundBlock (x, y);
}
bool checkAbove = CheckAboveBlock (x, y, 5);
if (checkAbove == false)
{
if (y < mossLevel)
{
if (mapData [x, y] == CubeTypes.Dirt)
{
if (roundingData [x, y] == CubeRounding.TopLeft || roundingData [x, y] == CubeRounding.TopMiddle || roundingData [x, y] == CubeRounding.TopRight)
{
mapData [x, y] = CubeTypes.DirtMoss;
}
}
else if (mapData [x, y] == CubeTypes.Cobblestone)
{
mapData [x, y] = CubeTypes.CobblestoneMoss;
}
}
else
{
if (roundingData [x, y] == CubeRounding.TopLeft || roundingData [x, y] == CubeRounding.TopMiddle || roundingData [x, y] == CubeRounding.TopRight)
{
mapData [x, y] = CubeTypes.Grass;
}
}
}
}
}
}
void CreateCubes (int direction) {
if (direction == -1)
{
GameObject currentChunk = Instantiate (chunkContainer, Vector3.zero, Quaternion.identity) as GameObject;
currentChunk.gameObject.name = "Chunk Container " + (width / 2 / chunkSize - leftmostChunk);
chunks [width / 2 / chunkSize - leftmostChunk] = currentChunk;
for (int x = 0; x < chunkSize; x ++)
{
for (int y = 0; y < height + hillHeight; y ++)
{
if (map != null && mapData != null)
{
if (map [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == Cubes.Yes)
{
Vector2 pos = new Vector3 ((float) x / 4 - chunkSize / 4 - leftmostChunk * chunkSize / 4 + 0.125f, (float) y / 4 + 0.125f);
if (mapData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == CubeTypes.Dirt)
{
switch (roundingData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y])
{
case CubeRounding.BottomLeft:
GameObject currentCube = Instantiate (dirt [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.BottomMiddle:
currentCube = Instantiate (dirt [1], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.BottomRight:
currentCube = Instantiate (dirt [2], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.MiddleLeft:
currentCube = Instantiate (dirt [3], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Middle:
currentCube = Instantiate (dirt [4], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.MiddleRight:
currentCube = Instantiate (dirt [5], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopLeft:
currentCube = Instantiate (dirt [6], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopMiddle:
currentCube = Instantiate (dirt [7], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopRight:
currentCube = Instantiate (dirt [8], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Bottom:
currentCube = Instantiate (dirt [9], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Left:
currentCube = Instantiate (dirt [10], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Right:
currentCube = Instantiate (dirt [11], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Top:
currentCube = Instantiate (dirt [12], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.LeftRight:
currentCube = Instantiate (dirt [13], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopBottom:
currentCube = Instantiate (dirt [14], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Single:
currentCube = Instantiate (dirt [15], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
}
}
else if (mapData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == CubeTypes.Grass)
{
GameObject currentCube = Instantiate (grass [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == CubeTypes.Cobblestone)
{
GameObject currentCube = Instantiate (cobblestone [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == CubeTypes.DirtMoss)
{
GameObject currentCube = Instantiate (dirt [7], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
currentCube = Instantiate (moss, pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 - chunkSize - leftmostChunk * chunkSize + x, y] == CubeTypes.CobblestoneMoss)
{
GameObject currentCube = Instantiate (cobblestone [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
currentCube = Instantiate (moss, pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
}
}
}
}
leftmostChunk ++;
}
else if (direction == 1)
{
GameObject currentChunk = Instantiate (chunkContainer, Vector3.zero, Quaternion.identity) as GameObject;
currentChunk.gameObject.name = "Chunk Container " + (width / 2 / chunkSize + rightmostChunk + 1);
chunks [width / 2 / chunkSize + rightmostChunk + 1] = currentChunk;
for (int x = 0; x < chunkSize; x ++)
{
for (int y = 0; y < height + hillHeight; y ++)
{
if (map != null && mapData != null)
{
if (map [width / 2 + rightmostChunk * chunkSize + x, y] == Cubes.Yes)
{
Vector2 pos = new Vector3 ((float) x / 4 + rightmostChunk * chunkSize / 4 + 0.125f, (float) y / 4 + 0.125f);
if (mapData [width / 2 + rightmostChunk * chunkSize + x, y] == CubeTypes.Dirt)
{
switch (roundingData [width / 2 + rightmostChunk * chunkSize + x, y])
{
case CubeRounding.BottomLeft:
GameObject currentCube = Instantiate (dirt [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.BottomMiddle:
currentCube = Instantiate (dirt [1], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.BottomRight:
currentCube = Instantiate (dirt [2], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.MiddleLeft:
currentCube = Instantiate (dirt [3], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Middle:
currentCube = Instantiate (dirt [4], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.MiddleRight:
currentCube = Instantiate (dirt [5], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopLeft:
currentCube = Instantiate (dirt [6], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopMiddle:
currentCube = Instantiate (dirt [7], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopRight:
currentCube = Instantiate (dirt [8], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Bottom:
currentCube = Instantiate (dirt [9], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Left:
currentCube = Instantiate (dirt [10], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Right:
currentCube = Instantiate (dirt [11], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Top:
currentCube = Instantiate (dirt [12], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.LeftRight:
currentCube = Instantiate (dirt [13], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.TopBottom:
currentCube = Instantiate (dirt [14], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
case CubeRounding.Single:
currentCube = Instantiate (dirt [15], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
break;
}
}
else if (mapData [width / 2 + rightmostChunk * chunkSize + x, y] == CubeTypes.Grass)
{
GameObject currentCube = Instantiate (grass [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 + rightmostChunk * chunkSize + x, y] == CubeTypes.Cobblestone)
{
GameObject currentCube = Instantiate (cobblestone [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 + rightmostChunk * chunkSize + x, y] == CubeTypes.DirtMoss)
{
GameObject currentCube = Instantiate (dirt [7], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
currentCube = Instantiate (moss, pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
else if (mapData [width / 2 + rightmostChunk * chunkSize + x, y] == CubeTypes.CobblestoneMoss)
{
GameObject currentCube = Instantiate (cobblestone [0], pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
currentCube = Instantiate (moss, pos, Quaternion.identity) as GameObject;
currentCube.transform.parent = currentChunk.transform;
}
}
}
}
}
rightmostChunk ++;
}
}
void RenderCubes (int c) {
if (c > -1 && c < width / chunkSize)
{
if (chunks [c] != null)
{
if (chunks [c].activeInHierarchy == true)
{
chunks [c].SetActive (true);
}
if (c == width / 2 / chunkSize - leftRender - 1)
{
leftRender ++;
}
else if (c == width / 2 / chunkSize + rightRender + 1)
{
rightRender ++;
}
}
}
}
void DeactivateCubes (int c) {
if (c > -1 && c < width / chunkSize)
{
if (chunks [c] != null)
{
if (chunks [c].activeInHierarchy == true)
{
chunks [c].SetActive (false);
}
if (c == width / 2 / chunkSize - leftRender)
{
leftRender --;
}
else if (c == width / 2 / chunkSize + rightRender)
{
rightRender --;
}
}
}
}
}
Comment
The renderL and renderR stuff is my first step to my attempt to make this.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Simple jump code 2D - c# 1 Answer
How do I end my level? 2 Answers
Need help with screen resolution and character size 1 Answer
Scrolling Repeated Background - background is scrolling but not repeating 0 Answers