Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2022-11-12 13:10:03 +01:00

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