По классике половина кода не моя. Да, вопросы?
Постараюсь объяснить как делать карту:
Шум
В интернете есть множество разных шумов, велосипед нам не нужен. Берем Accidental Noise. Надеюсь имеется минимальное знание C#.
C# синтаксиса тут нема. Довольствуемся просто текстом.
Для начала нам нужен контейнер где будут данные которые сгенерируются.
Создаем класс MapData, а в Min и Max будут записываться нижний и верхний предел значений.
public class MapData {
public float[,] Data;
public float Min { get; set; }
public float Max { get; set; }
public MapData(int width, int height)
{
Data = new float[width, height];
Min = float.MaxValue;
Max = float.MinValue;
}
}
Еще нам нужен класс для хранения объектов:
public class Tile
{
public float HeightValue { get; set; }
public int X, Y;
public Tile()
{
}
}
Создаем класс который нарисует ЧБ текстуру шума:
using UnityEngine;
public static class TextureGenerator {
public static Texture2D GetTexture(int width, int height, Tile[,] tiles)
{
var texture = new Texture2D(width, height);
var pixels = new Color[width * height];
for (var x = 0; x < width; x++)
{
for (var y = 0; y < height; y++)
{
float value = tiles[x, y].HeightValue;
//Set color range, 0 = black, 1 = white
pixels[x + y * width] = Color.Lerp (Color.black, Color.white, value);
}
}
texture.SetPixels(pixels);
texture.wrapMode = TextureWrapMode.Clamp;
texture.Apply();
return texture;
}
}
Делаем карту высот
Класс Generator инициализирует модуль Noise, генерирует данные карты высот, создает массив тайлов, а затем генерирует текстуру этих данных.
Желательно что бы Width и Height были кратные двум.
using UnityEngine;
using AccidentalNoise;
public class Generator : MonoBehaviour {
[SerializeField]
int Width = 256;
[SerializeField]
int Height = 256;
[SerializeField]
int TerrainOctaves = 6;
[SerializeField]
double TerrainFrequency = 1.25;
ImplicitFractal HeightMap;
MapData HeightData;
Tile[,] Tiles;
MeshRenderer HeightMapRenderer;
void Start()
{
HeightMapRenderer = transform.Find ("HeightTexture").GetComponent ();
Initialize ();
GetData (HeightMap, ref HeightData);
LoadTiles();
HeightMapRenderer.materials[0].mainTexture = TextureGenerator.GetTexture (Width, Height, Tiles);
}
private void Initialize()
{
HeightMap = new ImplicitFractal (FractalType.MULTI,
BasisType.SIMPLEX,
InterpolationType.QUINTIC,
TerrainOctaves,
TerrainFrequency,
UnityEngine.Random.Range (0, int.MaxValue));
}
private void GetData(ImplicitModuleBase module, ref MapData mapData)
{
mapData = new MapData (Width, Height);
for (var x = 0; x < Width; x++)
{
for (var y = 0; y < Height; y++)
{
float x1 = x / (float)Width;
float y1 = y / (float)Height;
float value = (float)HeightMap.Get (x1, y1);
if (value > mapData.Max) mapData.Max = value;
if (value < mapData.Min) mapData.Min = value;
mapData.Data[x,y] = value;
}
}
}
private void LoadTiles()
{
Tiles = new Tile[Width, Height];
for (var x = 0; x < Width; x++)
{
for (var y = 0; y < Height; y++)
{
Tile t = new Tile();
t.X = x;
t.Y = y;
float value = HeightData.Data[x, y];
value = (value - HeightData.Min) / (HeightData.Max - HeightData.Min);
t.HeightValue = value;
Tiles[x,y] = t;
}
}
}
}
У нас получится довольно тусклое ЧБ текстура. Поэтому пихаем такую маленькую проверку:
if (value < 0.4f)
pixels[x + y * width] = Color.blue;
else
pixels[x + y * width] = Color.white;
и у нас получается вот это:
Ну и если вы не глупые, можно сделать переменные высот и их цвета:
//Высоты
float DeepWater = 0.2f;
float ShallowWater = 0.4f;
float Sand = 0.5f;
float Grass = 0.7f;
float Forest = 0.8f;
float Rock = 0.9f;
float Snow = 1;
//цвета
private static Color DeepColor = new Color(0, 0, 0.5f, 1);
private static Color ShallowColor = new Color(25/255f, 25/255f, 150/255f, 1);
private static Color SandColor = new Color(240 / 255f, 240 / 255f, 64 / 255f, 1);
private static Color GrassColor = new Color(50 / 255f, 220 / 255f, 20 / 255f, 1);
private static Color ForestColor = new Color(16 / 255f, 160 / 255f, 0, 1);
private static Color RockColor = new Color(0.5f, 0.5f, 0.5f, 1);
private static Color SnowColor = new Color(1, 1, 1, 1);
В конце у нас получится типо этого:
Если искать, можно найти все.
Как все таки удобно читать код в отдельно созданных полях
А если бы был шарп, было бы лучше
добавим
Смотрел в сторону шума Перлина?
"Accidental Noise Library is a library for generating Perlin noise and other forms of noise in a modular fashion."
Eсли перейти по ссылке Accidental Noise