162 lines
6.0 KiB
C#
162 lines
6.0 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using General;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace Terrain {
|
|
public class World : MonoBehaviour {
|
|
public static int ChunkSize = 10;
|
|
public static int AnimationTimeout = 30;
|
|
|
|
public Material terrainMaterial;
|
|
public Material bushMaterial;
|
|
public Material treeMaterial;
|
|
public Shader noOutline;
|
|
public Shader outline;
|
|
public GameObject terrain;
|
|
public Player player;
|
|
|
|
private TextureManager _terrainTextureManager;
|
|
private TextureManager _bushTextureManager;
|
|
private TextureManager _treeTextureManager;
|
|
private readonly Dictionary<Vector2, Chunk> _chunks = new Dictionary<Vector2, Chunk>();
|
|
private readonly Dictionary<Vector2, object> _buildings = new Dictionary<Vector2, object>();
|
|
|
|
public bool ready;
|
|
|
|
public void Start() {
|
|
Debug.Log("Initializing States");
|
|
Random.InitState(Settings.Seed);
|
|
|
|
BoxCollider2D col = terrain.AddComponent<BoxCollider2D>();
|
|
col.size = new Vector2(Settings.WorldSize, Settings.WorldSize) * ChunkSize * 2;
|
|
col.isTrigger = true;
|
|
|
|
Debug.Log("Creating Texture Managers");
|
|
_terrainTextureManager = new TextureManager(terrainMaterial, new Vector2Int(64, 64), this);
|
|
_bushTextureManager = new TextureManager(bushMaterial, new Vector2Int(32, 32), this);
|
|
_treeTextureManager = new TextureManager(treeMaterial, new Vector2Int(128, 128), this);
|
|
|
|
StartCoroutine(GenerateWorld());
|
|
}
|
|
|
|
private IEnumerator GenerateWorld() {
|
|
Debug.Log("Generating World");
|
|
for (int x = -Settings.WorldSize; x < Settings.WorldSize; x++) {
|
|
for (int y = Settings.WorldSize; y > -Settings.WorldSize; y--) {
|
|
_chunks.Add(new Vector2(x, y), new Chunk(new Vector2(x, y), this));
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
player.OnWorldReady();
|
|
ready = true;
|
|
Debug.Log("Done");
|
|
}
|
|
|
|
public Vector2 GetTile(Vector2 pos) {
|
|
Vector2 tile = new Vector2(
|
|
Mathf.FloorToInt(pos.x),
|
|
Mathf.FloorToInt(pos.y)
|
|
);
|
|
return tile;
|
|
}
|
|
public Chunk GetChunk(Vector2 pos) {
|
|
try {
|
|
pos = GetTile(pos);
|
|
Vector2 chunkPos = new Vector2(
|
|
Mathf.FloorToInt(pos.x / ChunkSize),
|
|
Mathf.FloorToInt(pos.y / ChunkSize)
|
|
);
|
|
|
|
return _chunks[chunkPos];
|
|
}
|
|
catch (Exception) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public Block GetBlock(Vector2 pos) { return GetChunk(pos).GetBlock(pos); }
|
|
public Obstical GetObstical(Vector2 pos) { return GetChunk(pos).GetObstical(pos); }
|
|
public void AddObstical(Obstical obstical) { obstical.Chunk.AddObstical(obstical); }
|
|
public void RemoveObstical(Vector2 pos) { GetChunk(pos).RemoveObstical(pos); }
|
|
|
|
public void AddBuilding(GameObject building) {
|
|
_buildings.Add(building.transform.position, building);
|
|
}
|
|
|
|
public int GenerateBlock(Vector2 position, Chunk chunk) {
|
|
Vector2Int pos = new Vector2Int(
|
|
Mathf.FloorToInt(position.x),
|
|
Mathf.FloorToInt(position.y)
|
|
);
|
|
|
|
float noise = Noise.Get2DNoise(pos, -(Settings.WorldSize * 2), 0.2f) * 10;
|
|
if (noise >= 8) return Block.Water.Id;
|
|
if (noise >= 7.7f) return Block.WetSand.Id;
|
|
if (noise >= 7.5f) return Block.Sand.Id;
|
|
if (noise < 1.5f) {
|
|
chunk.AddObstical(new Sapling(pos, chunk));
|
|
return Block.Forest.Id;
|
|
}
|
|
|
|
if (Random.Range(0f, 1f) < 0.002f)
|
|
chunk.AddObstical(new Bush(pos, chunk, Random.Range(0, 29)));
|
|
return Block.Grass.Id;
|
|
}
|
|
|
|
private void Update() {
|
|
if (!ready) return;
|
|
foreach (var chunk in _chunks.Values) {
|
|
chunk.Update();
|
|
}
|
|
}
|
|
|
|
private int _currentAnimationFrame;
|
|
private int _globalAnimationFrame;
|
|
private void FixedUpdate() {
|
|
if (!ready) return;
|
|
_currentAnimationFrame++;
|
|
if (_currentAnimationFrame >= AnimationTimeout) {
|
|
_currentAnimationFrame = 0;
|
|
foreach (var chunk in _chunks.Values) {
|
|
chunk.OnAnimationFrameChange(_globalAnimationFrame);
|
|
}
|
|
_globalAnimationFrame++;
|
|
}
|
|
|
|
foreach (var chunk in _chunks.Values) {
|
|
chunk.FixedUpdate();
|
|
}
|
|
}
|
|
|
|
public TextureManager GetTerrainTextureManager() { return _terrainTextureManager; }
|
|
public TextureManager GetBushTextureManager() { return _bushTextureManager; }
|
|
public TextureManager GetTreeTextureManager() { return _treeTextureManager; }
|
|
}
|
|
|
|
public static class Noise {
|
|
public static float Get2DNoise(Vector2 pos, float offset, float scale) {
|
|
return Mathf.PerlinNoise((pos.x + 0.1f) / World.ChunkSize * scale + offset,
|
|
(pos.y + 0.1f) / World.ChunkSize * scale + offset);
|
|
}
|
|
|
|
public static bool Get3DNoise(Vector3 pos, float offset, float scale, float threshold) {
|
|
float x = (pos.x + offset + 0.1f) * scale;
|
|
float y = (pos.y + offset + 0.1f) * scale;
|
|
float z = (pos.z + offset + 0.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);
|
|
|
|
return ((AB + BC + AC + BA + CB + CA) / 6f > threshold);
|
|
}
|
|
}
|
|
}
|