LD50/Assets/Scripts/Chunk.cs
2022-04-05 02:09:50 +02:00

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();
}
}