Chunk Loading
Caves
This commit is contained in:
@@ -57,7 +57,7 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6443714940181712877}
|
||||
m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
|
||||
m_LocalPosition: {x: 0, y: -0.132, z: 0.024}
|
||||
m_LocalPosition: {x: 0, y: -0.092, z: 0.024}
|
||||
m_LocalScale: {x: 0.24999988, y: 0.24999988, z: 0.25}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4093383343133656141}
|
||||
|
||||
@@ -9,6 +9,7 @@ public class Chunk
|
||||
private Material material;
|
||||
private ChunkCoord chunkPosition;
|
||||
private World world;
|
||||
public bool active = false;
|
||||
|
||||
//rendering
|
||||
public GameObject gameObject;
|
||||
@@ -136,6 +137,17 @@ public class Chunk
|
||||
meshFilter.mesh = mesh;
|
||||
meshRenderer.material = material;
|
||||
collider.sharedMesh = mesh;
|
||||
active = true;
|
||||
}
|
||||
|
||||
public void DestroyMesh()
|
||||
{
|
||||
meshFilter.mesh = null;
|
||||
vertices.Clear();
|
||||
triangles.Clear();
|
||||
uv.Clear();
|
||||
collider.sharedMesh = null;
|
||||
active = false;
|
||||
}
|
||||
|
||||
public void Edit(byte x, byte y, byte z, byte blockID)
|
||||
|
||||
@@ -6,6 +6,7 @@ public class Data
|
||||
{
|
||||
public static int chunkWidth = 15, chunkHeight = 250;
|
||||
public static int textureAtlasSize = 16;
|
||||
public static int viewDistance = 9;
|
||||
|
||||
public static readonly Vector3[] vertices =
|
||||
{
|
||||
|
||||
@@ -277,10 +277,10 @@ public class Player : MonoBehaviour
|
||||
private float CheckUpSpeed(float upSpeed)
|
||||
{
|
||||
if (
|
||||
world.CheckBlock(new Vector3(transform.position.x - playerWidth, transform.position.y + upSpeed + 2f, transform.position.z - playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x + playerWidth, transform.position.y + upSpeed + 2f, transform.position.z - playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x + playerWidth, transform.position.y + upSpeed + 2f, transform.position.z + playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x - playerWidth, transform.position.y + upSpeed + 2f, transform.position.z + playerWidth))
|
||||
world.CheckBlock(new Vector3(transform.position.x - playerWidth, transform.position.y + upSpeed + 1.9f, transform.position.z - playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x + playerWidth, transform.position.y + upSpeed + 1.9f, transform.position.z - playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x + playerWidth, transform.position.y + upSpeed + 1.9f, transform.position.z + playerWidth)) ||
|
||||
world.CheckBlock(new Vector3(transform.position.x - playerWidth, transform.position.y + upSpeed + 1.9f, transform.position.z + playerWidth))
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -24,10 +24,12 @@ public class World : MonoBehaviour
|
||||
[SerializeField] private Player player;
|
||||
[SerializeField] private GameObject deadScreen;
|
||||
[SerializeField] private GameObject pauseScreen;
|
||||
private ChunkCoord lastPlayerChunkCoord = new ChunkCoord(0, 0);
|
||||
|
||||
//chunks
|
||||
private Chunk[,] chunks;
|
||||
private Queue<ChunkCoord> chunksToUpdate = new Queue<ChunkCoord>();
|
||||
private List<Chunk> lastActiveChunks = new List<Chunk>();
|
||||
|
||||
//blocks
|
||||
[SerializeField] public BlockData[] blockData;
|
||||
@@ -54,6 +56,17 @@ public class World : MonoBehaviour
|
||||
|
||||
private void Update()
|
||||
{
|
||||
ChunkCoord playerChunkCoord = new ChunkCoord((int)(player.transform.position.x / Data.chunkWidth),
|
||||
(int)(player.transform.position.z / Data.chunkWidth));
|
||||
|
||||
if (lastPlayerChunkCoord.x != playerChunkCoord.x || lastPlayerChunkCoord.z != playerChunkCoord.z)
|
||||
{
|
||||
LoadChunks(playerChunkCoord);
|
||||
}
|
||||
|
||||
lastPlayerChunkCoord = new ChunkCoord((int)(player.transform.position.x / Data.chunkWidth),
|
||||
(int)(player.transform.position.z / Data.chunkWidth));
|
||||
|
||||
//update 1 chunk in list
|
||||
if (chunksToUpdate.Count > 0)
|
||||
{
|
||||
@@ -107,6 +120,41 @@ public class World : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadChunks(ChunkCoord playerChunk)
|
||||
{
|
||||
List<Chunk> checkList = new List<Chunk>();
|
||||
|
||||
for (int x = playerChunk.x - Data.viewDistance; x < playerChunk.x + Data.viewDistance; x++)
|
||||
{
|
||||
for (int z = playerChunk.z - Data.viewDistance; z < playerChunk.z + Data.viewDistance; z++)
|
||||
{
|
||||
if(chunks[x, z].gameObject == null)
|
||||
{
|
||||
chunks[x, z].Initialize();
|
||||
chunks[x, z].gameObject.transform.SetParent(gameObject.transform);
|
||||
}
|
||||
if(!chunks[x, z].active)
|
||||
{
|
||||
chunksToUpdate.Enqueue(new ChunkCoord(x, z));
|
||||
}
|
||||
checkList.Add(chunks[x, z]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Chunk c in lastActiveChunks)
|
||||
{
|
||||
if (!checkList.Contains(c))
|
||||
{
|
||||
c.DestroyMesh();
|
||||
}
|
||||
}
|
||||
|
||||
lastActiveChunks.Clear();
|
||||
|
||||
lastActiveChunks = new List<Chunk>(checkList);
|
||||
}
|
||||
|
||||
|
||||
//enqueue player position update to list
|
||||
public void UpdatePlayerPosition(Vector3 position, byte id)
|
||||
{
|
||||
@@ -149,14 +197,14 @@ public class World : MonoBehaviour
|
||||
//initialized the chunk objects
|
||||
public void CreateChunks()
|
||||
{
|
||||
for (int x = 0; x < worldSize; x++)
|
||||
for (int x = worldSize / 2 - Data.viewDistance; x < worldSize / 2 + Data.viewDistance; x++)
|
||||
{
|
||||
for (int z = 0; z < worldSize; z++)
|
||||
for (int z = worldSize / 2 - Data.viewDistance; z < worldSize / 2 + Data.viewDistance; z++)
|
||||
{
|
||||
chunks[x, z].Initialize();
|
||||
chunks[x, z].gameObject.transform.SetParent(gameObject.transform);
|
||||
chunks[x, z].AddBlocks();
|
||||
chunks[x, z].CreateMesh();
|
||||
chunksToUpdate.Enqueue(new ChunkCoord(x, z));
|
||||
lastActiveChunks.Add(chunks[x, z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,11 +261,11 @@ public class World : MonoBehaviour
|
||||
int zInChunk = z - (zChunk * Data.chunkWidth);
|
||||
|
||||
Chunk c = chunks[xChunk, zChunk];
|
||||
for (int y = 0; y < Data.chunkHeight; y++)
|
||||
for (int y = Data.chunkHeight - 1; y > 0; y--)
|
||||
{
|
||||
if (c.blocks[xInChunk, y, zInChunk] == 0)
|
||||
if (c.blocks[xInChunk, y, zInChunk] != 0)
|
||||
{
|
||||
return (byte)(y - 1);
|
||||
return (byte)(y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,6 +357,8 @@ public class World : MonoBehaviour
|
||||
Time.timeScale = 1;
|
||||
player.transform.position = player.GetDefaultPlayerPosition();
|
||||
deadScreen.SetActive(false);
|
||||
LoadChunks(new ChunkCoord((int)(player.transform.position.x / Data.chunkWidth),
|
||||
(int)(player.transform.position.z / Data.chunkWidth)));
|
||||
}
|
||||
|
||||
public void ResumeButton()
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Noise
|
||||
{
|
||||
public byte GetHeight(int x, int z, int randomOffsetX, int randomOffsetZ)
|
||||
{
|
||||
float scale = 0.025f;
|
||||
byte perlinHeight = 10;
|
||||
byte groundHeight = 50;
|
||||
|
||||
byte height = (byte)(Mathf.PerlinNoise((x + randomOffsetX) * scale + 0.1f, (z + randomOffsetZ) * scale + 0.1f) * perlinHeight + groundHeight);
|
||||
return height;
|
||||
}
|
||||
|
||||
public bool CheckTree(int x, int z)
|
||||
{
|
||||
float scale = .99f;
|
||||
float threshold = .96f;
|
||||
|
||||
if (Mathf.PerlinNoise((x) * scale + 0.1f, (z) * scale + 0.1f) >= threshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Get3DPerlin(Vector3 position, float offset, float scale, float threshold)
|
||||
{
|
||||
float x = (position.x + offset + .1f) * scale;
|
||||
float y = (position.y + offset + .1f) * scale;
|
||||
float z = (position.z + offset + .1f) * scale;
|
||||
|
||||
float AB = Mathf.PerlinNoise(x, y);
|
||||
float BC = Mathf.PerlinNoise(y, z);
|
||||
float AC = Mathf.PerlinNoise(x, z);
|
||||
|
||||
float BA = Mathf.PerlinNoise(y, x);
|
||||
float CB = Mathf.PerlinNoise(z, y);
|
||||
float CA = Mathf.PerlinNoise(z, x);
|
||||
|
||||
if ((AB + BC + AC + BA + CB + CA) / 6f > threshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dedaa2ec7a8b12443a08f16cad880f84
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,6 +13,7 @@ public class World : MonoBehaviour
|
||||
private int randomOffsetX, randomOffsetZ;
|
||||
private int seed = 0;
|
||||
private string dataPath;
|
||||
private Noise noise = new Noise();
|
||||
|
||||
//chunks
|
||||
public Chunk[,] chunks;
|
||||
@@ -29,6 +30,8 @@ public class World : MonoBehaviour
|
||||
|
||||
if (File.Exists(Application.dataPath + "\\save.world"))
|
||||
{
|
||||
Console.WriteLine("loading world... \n");
|
||||
|
||||
chunks = new Chunk[worldSize, worldSize];
|
||||
for (int x = 0; x < worldSize; x++)
|
||||
{
|
||||
@@ -65,6 +68,8 @@ public class World : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("generate world... \n");
|
||||
|
||||
CreateChunks();
|
||||
CreateTrees();
|
||||
}
|
||||
@@ -102,12 +107,12 @@ public class World : MonoBehaviour
|
||||
{
|
||||
for (int z = 4; z < worldSize * Data.chunkWidth - 4; z++)
|
||||
{
|
||||
if (CheckTree(x, z))
|
||||
if (noise.CheckTree(x, z))
|
||||
{
|
||||
ChunkCoord chunk = new ChunkCoord((int)(x / Data.chunkWidth),
|
||||
(int)(z / Data.chunkWidth));
|
||||
int xInChunk = (int)(x - chunk.x * Data.chunkWidth);
|
||||
int yInChunk = (int)(GetHeight(x, z));
|
||||
int yInChunk = (int)(noise.GetHeight(x, z, randomOffsetX, randomOffsetZ));
|
||||
int zInChunk = (int)(z - chunk.z * Data.chunkWidth);
|
||||
|
||||
int height = Random.Range(5, 9);
|
||||
@@ -157,11 +162,6 @@ public class World : MonoBehaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ public class World : MonoBehaviour
|
||||
//return the ID of a block
|
||||
public byte GetBlockID(Vector3 positionInWorld)
|
||||
{
|
||||
byte height = GetHeight((int)positionInWorld.x, (int)positionInWorld.z);
|
||||
byte height = noise.GetHeight((int)positionInWorld.x, (int)positionInWorld.z, randomOffsetX, randomOffsetZ);
|
||||
|
||||
//world pass
|
||||
if (positionInWorld.x < 0 || positionInWorld.y < 0 || positionInWorld.z < 0 ||
|
||||
@@ -180,24 +180,37 @@ public class World : MonoBehaviour
|
||||
return 0;
|
||||
}
|
||||
|
||||
//chunk pass
|
||||
//surface pass
|
||||
if ((int)positionInWorld.y == height)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
//bedrock pass
|
||||
if ((int)positionInWorld.y == 0)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//dirt pass
|
||||
if ((int)positionInWorld.y > height - 3)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
//underground pass
|
||||
if ((int)positionInWorld.y < height)
|
||||
{
|
||||
//caves
|
||||
if((int)positionInWorld.y > 6 && (int)positionInWorld.y < height - 8)
|
||||
{
|
||||
if (noise.Get3DPerlin(positionInWorld, 0, 0.18f, 0.5f))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -240,30 +253,6 @@ public class World : MonoBehaviour
|
||||
return true;
|
||||
}
|
||||
|
||||
private byte GetHeight(int x, int z)
|
||||
{
|
||||
float scale = 0.025f;
|
||||
byte perlinHeight = 10;
|
||||
byte groundHeight = 10;
|
||||
|
||||
byte height = (byte)(Mathf.PerlinNoise((x + randomOffsetX) * scale + 0.1f, (z + randomOffsetZ) * scale + 0.1f) * perlinHeight + groundHeight);
|
||||
return height;
|
||||
}
|
||||
|
||||
private bool CheckTree(int x, int z)
|
||||
{
|
||||
float scale = .99f;
|
||||
float threshold = .96f;
|
||||
|
||||
if (Mathf.PerlinNoise((x) * scale + 0.1f, (z) * scale + 0.1f) >= threshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public void EditBlock(ChunkCoord chunk, Vector3 positionInChunk, byte blockID)
|
||||
{
|
||||
byte xInChunk = (byte)(positionInChunk.x);
|
||||
@@ -311,6 +300,6 @@ public class World : MonoBehaviour
|
||||
}
|
||||
}
|
||||
writer.Close();
|
||||
Console.WriteLine("world saved! \n");
|
||||
Console.WriteLine("world saved! (world.save) \n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,5 +166,5 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 5457f26f725053d46bffb9885acfd7d8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
worldSize: 20
|
||||
worldSize: 60
|
||||
transferDelay: 5
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 940041af630d8d944ac3b74467aa4ae7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user