142 lines
6.0 KiB
C#
142 lines
6.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class Chunk : MonoBehaviour
|
|
{
|
|
private Mesh mesh;
|
|
|
|
private const int MESH_RESOLUTION_X = 64;
|
|
private const int MESH_RESOLUTION_Y = 64;
|
|
public const float CHUNK_SIZE = 64.0f;
|
|
private const float MESH_TILE_RES = CHUNK_SIZE / MESH_RESOLUTION_X;
|
|
|
|
private List<GameObject> localPooledPrefabs = new List<GameObject>();
|
|
|
|
protected void Awake()
|
|
{
|
|
mesh = new Mesh();
|
|
Vector3[] vertices = new Vector3[MESH_RESOLUTION_X * MESH_RESOLUTION_Y * 4];
|
|
int[] triangles = new int[MESH_RESOLUTION_X*MESH_RESOLUTION_Y*3*2];
|
|
|
|
int vertIndex = 0;
|
|
int triangleIndex = 0;
|
|
|
|
for(int x=0; x<MESH_RESOLUTION_X; x++)
|
|
{
|
|
for(int y=0; y<MESH_RESOLUTION_Y; y++)
|
|
{
|
|
vertices[vertIndex+0] = (new Vector3(x, 0.0f, y)) * MESH_TILE_RES;
|
|
vertices[vertIndex+1] = (new Vector3(x+1, 0.0f, y)) * MESH_TILE_RES;
|
|
vertices[vertIndex+2] = (new Vector3(x, 0.0f, y+1)) * MESH_TILE_RES;
|
|
vertices[vertIndex+3] = (new Vector3(x+1, 0.0f, y+1)) * MESH_TILE_RES;
|
|
|
|
triangles[triangleIndex+0] = vertIndex+2;
|
|
triangles[triangleIndex+1] = vertIndex+1;
|
|
triangles[triangleIndex+2] = vertIndex+0;
|
|
triangles[triangleIndex+3] = vertIndex+1;
|
|
triangles[triangleIndex+4] = vertIndex+2;
|
|
triangles[triangleIndex+5] = vertIndex+3;
|
|
|
|
vertIndex += 4;
|
|
triangleIndex += 6;
|
|
}
|
|
}
|
|
|
|
mesh.vertices = vertices;
|
|
mesh.triangles = triangles;
|
|
mesh.Optimize();
|
|
mesh.RecalculateNormals();
|
|
|
|
GetComponent<MeshFilter>().mesh = mesh;
|
|
MeshCollider meshCollider = GetComponent<MeshCollider>();
|
|
meshCollider.sharedMesh = mesh;
|
|
}
|
|
|
|
public void UpdateMesh()
|
|
{
|
|
Vector3[] vertices = mesh.vertices;
|
|
Vector3 vertex;
|
|
Vector3 worldSpaceVertexPosition;
|
|
for(int n=0;n<vertices.Length;n++)
|
|
{
|
|
vertex = vertices[n];
|
|
worldSpaceVertexPosition = this.transform.TransformPoint(vertex);
|
|
vertices[n] = new Vector3(vertex.x, TerrainGenerator.Instance.GetHeight(worldSpaceVertexPosition.x, worldSpaceVertexPosition.z), vertex.z);
|
|
}
|
|
|
|
mesh.vertices = vertices;
|
|
mesh.RecalculateNormals();
|
|
mesh.RecalculateBounds();
|
|
}
|
|
|
|
public void UpdatePosition(Vector3 newPos)
|
|
{
|
|
this.transform.position = newPos;
|
|
foreach(GameObject g in localPooledPrefabs)
|
|
PoolManager.Instance.ReturnInstance(g);
|
|
|
|
localPooledPrefabs.Clear();
|
|
|
|
List<Vector2> points = PoissonDiscSampling.GeneratePoints(7.0f, new Vector2(CHUNK_SIZE, CHUNK_SIZE));
|
|
Vector2 globalPos = new Vector2(this.transform.position.x, this.transform.position.z);
|
|
foreach(Vector2 point in points)
|
|
{
|
|
Vector2 globalPoint = point + globalPos;
|
|
float noise_scale = 0.1f;
|
|
float noise = Mathf.PerlinNoise(1000.0f + globalPoint.x * noise_scale, 1000.0f + globalPoint.y * noise_scale) * 2.0f - 1.0f;
|
|
float distanceFromPath = TerrainGenerator.Instance.GetDistanceFromPath(globalPoint.x, globalPoint.y);
|
|
float height = TerrainGenerator.Instance.GetHeight(globalPoint.x, globalPoint.y);
|
|
if(height < 16.0f && noise > 0.01f && Mathf.Abs(distanceFromPath) > 1.0f)
|
|
{
|
|
GameObject g = PoolManager.Instance.GetInstance(TerrainGenerator.Instance.TreePrefab);
|
|
if(g != null)
|
|
{
|
|
g.transform.position = new Vector3(globalPoint.x, height, globalPoint.y);
|
|
localPooledPrefabs.Add(g);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.transform.position.x == 0 && this.transform.position.z > 0)
|
|
{
|
|
int MAX_TREES_PATH = 8;
|
|
int additionalTrees = (int)Random.Range(0, MAX_TREES_PATH);
|
|
for(int n=0;n<additionalTrees;n++)
|
|
{
|
|
float yTreeOffset = n * (CHUNK_SIZE/MAX_TREES_PATH) + Random.Range(0.0f, (CHUNK_SIZE/MAX_TREES_PATH) * 0.25f) + this.transform.position.z;
|
|
float xTreeOffset = TerrainGenerator.Instance.GetPathCenter(yTreeOffset) * 15.0f + (Random.Range(-1.0f, 1.0f) * 10.0f);
|
|
Vector2 treePos = new Vector2(xTreeOffset, yTreeOffset);
|
|
float height = TerrainGenerator.Instance.GetHeight(treePos.x, treePos.y);
|
|
|
|
GameObject g = PoolManager.Instance.GetInstance(TerrainGenerator.Instance.SnowmanObstaclePrefab);
|
|
if(g != null)
|
|
{
|
|
g.transform.position = new Vector3(treePos.x, height, treePos.y);
|
|
g.transform.rotation = Quaternion.identity * Quaternion.AngleAxis(180.0f, Vector3.up);
|
|
localPooledPrefabs.Add(g);
|
|
}
|
|
}
|
|
|
|
int MAX_PICKUPITEMS_PATH = 1;
|
|
int pickupItemCount = (Random.Range(0.0f, 1.0f) * 1000.0f) > this.transform.position.z || Random.Range(0.0f, 1.0f) < 0.25f ? MAX_PICKUPITEMS_PATH : 0;
|
|
for(int n=0;n<pickupItemCount;n++)
|
|
{
|
|
float yItemOffset = n * (CHUNK_SIZE/MAX_PICKUPITEMS_PATH) + Random.Range(0.0f, (CHUNK_SIZE/MAX_PICKUPITEMS_PATH) * 0.75f + 0.5f ) + this.transform.position.z;
|
|
float xItemOffset = TerrainGenerator.Instance.GetPathCenter(yItemOffset) * 15.0f + (Random.Range(-1.0f, 1.0f) * 10.0f);
|
|
Vector2 itemPos = new Vector2(xItemOffset, yItemOffset);
|
|
float height = TerrainGenerator.Instance.GetHeight(itemPos.x, itemPos.y);
|
|
|
|
GameObject g = PoolManager.Instance.GetInstance(TerrainGenerator.Instance.PickupPrefab);
|
|
if(g != null)
|
|
{
|
|
g.transform.position = new Vector3(itemPos.x, height, itemPos.y);
|
|
localPooledPrefabs.Add(g);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.UpdateMesh();
|
|
}
|
|
}
|