diff --git a/Demo/Demo-URP.unitypackage b/Demo/Demo-URP.unitypackage
index 4e24d10..4aae923 100644
Binary files a/Demo/Demo-URP.unitypackage and b/Demo/Demo-URP.unitypackage differ
diff --git a/Images/Sample_01.PNG b/Images/Sample_01.PNG
new file mode 100644
index 0000000..5829dd5
Binary files /dev/null and b/Images/Sample_01.PNG differ
diff --git a/Images/Sample_01.PNG.meta b/Images/Sample_01.PNG.meta
new file mode 100644
index 0000000..9d6c9a8
--- /dev/null
+++ b/Images/Sample_01.PNG.meta
@@ -0,0 +1,92 @@
+fileFormatVersion: 2
+guid: c5997898c14b56445b53085a70d1c27e
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 11
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: -1
+ aniso: -1
+ mipBias: -100
+ wrapU: -1
+ wrapV: -1
+ wrapW: -1
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ applyGammaDecoding: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spritePackingTag:
+ pSDRemoveMatte: 0
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/README.md b/README.md
index 9f964a3..aa6f6da 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Library of utilitities for procedural generation
#### Using UnityPackageManager (for Unity 2019.3 or later)
Open the package manager window (menu: Window > Package Manager)
Select "Add package from git URL...", fill in the pop-up with the following link:
-https://github.com/coryleach/UnityProcgen.git#0.0.2
+https://github.com/coryleach/UnityProcgen.git#0.0.3
#### Using UnityPackageManager (for Unity 2019.1 or later)
@@ -21,7 +21,7 @@ Find the manifest.json file in the Packages folder of your project and edit it t
```js
{
"dependencies": {
- "com.gameframe.procgen": "https://github.com/coryleach/UnityProcgen.git#0.0.2",
+ "com.gameframe.procgen": "https://github.com/coryleach/UnityProcgen.git#0.0.3",
...
},
}
@@ -30,6 +30,8 @@ Find the manifest.json file in the Packages folder of your project and edit it t
## Sample Output
+
+
## Usage
diff --git a/Runtime/Utility/HexMeshUtility.cs b/Runtime/Utility/HexMeshUtility.cs
new file mode 100644
index 0000000..1c5860f
--- /dev/null
+++ b/Runtime/Utility/HexMeshUtility.cs
@@ -0,0 +1,301 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Gameframe.Procgen
+{
+ public enum HexDirection
+ {
+ NE = 0,
+ E = 1,
+ SE = 2,
+ SW = 3,
+ W = 4,
+ NW = 5
+ }
+
+ public class HexMeshData
+ {
+ public float outerRadius;
+ public float innerRadius;
+ public List vertices;
+ public List triangles;
+ public List colors;
+ public List uv;
+ public Vector3[] corners;
+
+ private float border = 0.25f;
+
+ public float Border => border;
+ public float Solid => 1 - border;
+
+ public HexMeshData()
+ {
+ }
+
+ public HexMeshData(float radius, float border = 0.2f)
+ {
+ this.border = Mathf.Clamp01(border);
+
+ outerRadius = radius;
+ innerRadius = outerRadius * Mathf.Sqrt(3f) * 0.5f;
+ vertices = new List();
+ triangles = new List();
+ colors = new List();
+ uv = new List();
+ corners = new [] {
+ new Vector3(0f, 0f, outerRadius),
+ new Vector3(innerRadius, 0f, 0.5f * outerRadius),
+ new Vector3(innerRadius, 0f, -0.5f * outerRadius),
+ new Vector3(0f, 0f, -outerRadius),
+ new Vector3(-innerRadius, 0f, -0.5f * outerRadius),
+ new Vector3(-innerRadius, 0f, 0.5f * outerRadius),
+ new Vector3(0f, 0f, outerRadius)
+ };
+ }
+
+ public Vector3 GetBridge(HexDirection direction)
+ {
+ return (corners[(int)direction] + corners[(int)direction + 1]) * 0.5f * border;
+ }
+
+ public Vector3 GetFirstCorner(HexDirection direction)
+ {
+ return corners[(int) direction];
+ }
+
+ public Vector3 GetSecondCorner(HexDirection direction)
+ {
+ return corners[(int) direction + 1];
+ }
+
+ public Vector3 GetFirstSolidCorner(HexDirection direction)
+ {
+ return corners[(int) direction] * Solid;
+ }
+
+ public Vector3 GetSecondSolidCorner(HexDirection direction)
+ {
+ return corners[(int) direction + 1] * Solid;
+ }
+
+ public Mesh CreateMesh()
+ {
+ Mesh mesh = new Mesh();
+ mesh.vertices = vertices.ToArray();
+ mesh.triangles = triangles.ToArray();
+ mesh.colors = colors.ToArray();
+ mesh.uv = uv.ToArray();
+ mesh.RecalculateNormals();
+ return mesh;
+ }
+
+ }
+
+ public static class HexMeshUtility
+ {
+ public static HexDirection Previous(this HexDirection direction)
+ {
+ return direction == HexDirection.NE ? HexDirection.NW : (direction - 1);
+ }
+
+ public static HexDirection Next(this HexDirection direction)
+ {
+ return direction == HexDirection.NW ? HexDirection.NE : (direction + 1);
+ }
+
+ public static int GetNeighbor(int index, HexDirection hexDirection, int mapWidth, int mapHeight)
+ {
+ int y = index / mapWidth;
+ int x = index - (y * mapWidth);
+
+ switch (hexDirection)
+ {
+ case HexDirection.NE:
+ //Only odd numbered rows shift a column
+ if ((y & 1) == 1)
+ {
+ x++;
+ }
+ y++;
+ break;
+ case HexDirection.E:
+ x++;
+ break;
+ case HexDirection.SE:
+ //Only odd numbered rows shift a column
+ if ((y & 1) == 1)
+ {
+ x++;
+ }
+ y--;
+ break;
+ case HexDirection.SW:
+ //Only even numbered rows shift a column
+ if ((y & 1) == 0)
+ {
+ x--;
+ }
+ y--;
+ break;
+ case HexDirection.W:
+ x--;
+ break;
+ case HexDirection.NW:
+ //Only even numbered rows shift a column
+ if ((y & 1) == 0)
+ {
+ x--;
+ }
+ y++;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(hexDirection), hexDirection, null);
+ }
+
+ if (x < 0 || x >= mapWidth)
+ {
+ return -1;
+ }
+
+ if (y < 0 || y >= mapHeight)
+ {
+ return -1;
+ }
+
+ return y * mapWidth + x;
+ }
+
+ public static Mesh GenerateHexagonMesh(float radius, float border, int startX, int startY, int chunkWidth, int chunkHeight, int mapWidth, int mapHeight, float[] heightMap, Func colorFunction, Func elevationFunction)
+ {
+ var meshData = new HexMeshData(radius, border);
+
+ for (int dy = 0; dy < chunkHeight && (startY + dy) < mapHeight; dy++)
+ {
+ for (int dx = 0; dx < chunkWidth && (startX + dx) < mapWidth; dx++)
+ {
+ int x = startX + dx;
+ int y = startY + dy;
+
+ var index = (y * mapWidth) + x;
+
+ var xOffset = x + y * 0.5f - (int)(y / 2);
+ var center = new Vector3(xOffset*meshData.innerRadius*2,0,y*meshData.outerRadius*1.5f);
+
+ for (var direction = 0; direction < 6; direction++)
+ {
+ var elevation = elevationFunction?.Invoke(heightMap[index]) ?? 0;
+ var previousNeighborElevation = elevation;
+ var neighborElevation = elevation;
+ var nextNeighborElevation = elevation;
+
+ var neighbor = GetNeighbor(index, (HexDirection)direction, mapWidth, mapHeight);
+ if (neighbor != -1)
+ {
+ neighborElevation = Mathf.Min(elevation,elevationFunction?.Invoke(heightMap[neighbor]) ?? 0);
+ }
+
+ neighbor = GetNeighbor(index, ((HexDirection)direction).Previous(), mapWidth, mapHeight);
+ if (neighbor != -1)
+ {
+ previousNeighborElevation = Mathf.Min(elevation,elevationFunction?.Invoke(heightMap[neighbor]) ?? 0);
+ }
+
+ neighbor = GetNeighbor(index, ((HexDirection)direction).Next(), mapWidth, mapHeight);
+ if (neighbor != -1)
+ {
+ nextNeighborElevation = Mathf.Min(elevation,elevationFunction?.Invoke(heightMap[neighbor]) ?? 0);
+ }
+
+ center.y = elevation;
+
+ var color = colorFunction?.Invoke(heightMap[index]) ?? Color.white;
+ var uv = new Vector2(x / (float)mapWidth, y / (float)mapHeight);
+ AddTriangle(meshData, center, uv, neighborElevation, previousNeighborElevation, nextNeighborElevation, (HexDirection)direction, color);
+ }
+
+ }
+ }
+
+ return meshData.CreateMesh();
+ }
+
+ private static void AddTriangle(HexMeshData meshData, Vector3 center, Vector3 uv, float neighborElevation, float previousElevation, float nextElevation, HexDirection direction, Color color)
+ {
+ var v1 = center;
+ var v2 = center + meshData.GetFirstSolidCorner(direction);
+ var v3 = center + meshData.GetSecondSolidCorner(direction);
+
+ //Add inner solid triangle
+ AddTriangle(meshData, v1, v2, v3, color, uv);
+
+ //Add Quad To Fill Border Gap
+ var v4 = v2 + meshData.GetBridge(direction);
+ v4.y = neighborElevation;
+ var v5 = v3 + meshData.GetBridge(direction);
+ v5.y = neighborElevation;
+ AddQuad(meshData, v2, v3, v4, v5, color, uv);
+
+ //Add Triangles to fill gap on sides of quad
+ var v6 = center + meshData.GetFirstCorner(direction);
+ v6.y = Mathf.Min(neighborElevation,previousElevation);
+ AddTriangle(meshData,v2, v6, v4, color, uv);
+
+ var v7 = center + meshData.GetSecondCorner(direction);
+ v7.y = Mathf.Min(neighborElevation,nextElevation);
+ AddTriangle(meshData, v3, v5, v7, color, uv);
+ }
+
+ private static void AddTriangle(HexMeshData meshData, Vector3 v1, Vector3 v2, Vector3 v3, Color color, Vector3 uv)
+ {
+ var vertexIndex = meshData.vertices.Count;
+
+ meshData.vertices.Add(v1);
+ meshData.vertices.Add(v2);
+ meshData.vertices.Add(v3);
+
+ meshData.colors.Add(color);
+ meshData.colors.Add(color);
+ meshData.colors.Add(color);
+
+ meshData.uv.Add(uv);
+ meshData.uv.Add(uv);
+ meshData.uv.Add(uv);
+
+ meshData.triangles.Add(vertexIndex);
+ meshData.triangles.Add(vertexIndex + 1);
+ meshData.triangles.Add(vertexIndex + 2);
+ }
+
+ private static void AddQuad(HexMeshData meshData, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color, Vector3 uv)
+ {
+ var vertexIndex = meshData.vertices.Count;
+
+ meshData.vertices.Add(v1);
+ meshData.vertices.Add(v2);
+ meshData.vertices.Add(v3);
+ meshData.vertices.Add(v4);
+
+ meshData.colors.Add(color);
+ meshData.colors.Add(color);
+ meshData.colors.Add(color);
+ meshData.colors.Add(color);
+
+ meshData.uv.Add(uv);
+ meshData.uv.Add(uv);
+ meshData.uv.Add(uv);
+ meshData.uv.Add(uv);
+
+ meshData.triangles.Add(vertexIndex);
+ meshData.triangles.Add(vertexIndex + 2);
+ meshData.triangles.Add(vertexIndex + 1);
+
+ meshData.triangles.Add(vertexIndex + 1);
+ meshData.triangles.Add(vertexIndex + 2);
+ meshData.triangles.Add(vertexIndex + 3);
+ }
+
+ }
+}
+
+
diff --git a/Runtime/Utility/HexMeshUtility.cs.meta b/Runtime/Utility/HexMeshUtility.cs.meta
new file mode 100644
index 0000000..8ea055e
--- /dev/null
+++ b/Runtime/Utility/HexMeshUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 94e4d100d2a68884f9b173860f59541c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Utility/TerrainMeshUtility.cs b/Runtime/Utility/TerrainMeshUtility.cs
index 75db20d..ccbdf68 100644
--- a/Runtime/Utility/TerrainMeshUtility.cs
+++ b/Runtime/Utility/TerrainMeshUtility.cs
@@ -1,4 +1,6 @@
-using UnityEngine;
+using System;
+using UnityEditor.SceneManagement;
+using UnityEngine;
namespace Gameframe.Procgen
{
@@ -7,7 +9,7 @@ public static class TerrainMeshUtility
{
private const int mapChunkSize = 241;
- public static MeshData GenerateMesh(float[] heightMap, int width, int height, int levelOfDetail)
+ public static MeshData GenerateMesh(float[] heightMap, int width, int height, int levelOfDetail, Func stepFunction, Func colorFunction = null)
{
float topLeftX = (width - 1) / -2f;
float topLeftZ = (height - 1) / 2f;
@@ -16,7 +18,7 @@ public static MeshData GenerateMesh(float[] heightMap, int width, int height, in
int vertsPerLine = (width - 1) / lodIncrement + 1;
int vertsPerColumn = (height - 1) / lodIncrement + 1;
- var meshData = new MeshData(vertsPerLine, vertsPerColumn);
+ var meshData = new MeshData(vertsPerLine, vertsPerColumn, colorFunction != null);
int vertIndex = 0;
int triangleIndex = 0;
for (int i = 0; i < vertsPerColumn; i++)
@@ -26,9 +28,14 @@ public static MeshData GenerateMesh(float[] heightMap, int width, int height, in
int x = j * lodIncrement;
int y = i * lodIncrement;
- meshData.vertices[vertIndex] = new Vector3(topLeftX + x, heightMap[y * width + x], topLeftZ - y);
+ meshData.vertices[vertIndex] = new Vector3(topLeftX + x, stepFunction.Invoke(heightMap[y * width + x]), topLeftZ - y);
meshData.uv[vertIndex] = new Vector2(x / (float) width, y / (float) height);
+ if (colorFunction != null)
+ {
+ meshData.colors[vertIndex] = colorFunction.Invoke(heightMap[y * width + x]);
+ }//*/
+
if (j < (vertsPerLine - 1) && i < (vertsPerColumn - 1))
{
triangleIndex = meshData.AddTriangle(triangleIndex, vertIndex, vertIndex + vertsPerLine + 1,
@@ -39,9 +46,14 @@ public static MeshData GenerateMesh(float[] heightMap, int width, int height, in
vertIndex++;
}
}
-
+
return meshData;
}
+
+ public static MeshData GenerateMesh(float[] heightMap, int width, int height, float heightScale, int levelOfDetail)
+ {
+ return GenerateMesh(heightMap, width, height, levelOfDetail, x => heightScale * x);
+ }
}
public class MeshData
@@ -49,6 +61,7 @@ public class MeshData
public readonly Vector3[] vertices;
public readonly int[] triangles;
public readonly Vector2[] uv;
+ public readonly Color[] colors;
public MeshData(Vector3[] vertices, int[] triangles, Vector2[] uv)
{
@@ -56,13 +69,24 @@ public MeshData(Vector3[] vertices, int[] triangles, Vector2[] uv)
this.triangles = triangles;
this.uv = uv;
}
+
+ public MeshData(Vector3[] vertices, int[] triangles, Vector2[] uv, Color[] colors)
+ {
+ this.vertices = vertices;
+ this.triangles = triangles;
+ this.uv = uv;
+ this.colors = colors;
+ }
- public MeshData(int vertsWide, int vertsHigh)
+ public MeshData(int vertsWide, int vertsHigh, bool vertexColors = false)
{
vertices = new Vector3[vertsWide * vertsHigh];
uv = new Vector2[vertsWide * vertsHigh];
triangles = new int[(vertsWide - 1) * (vertsHigh - 1) * 6];
-
+ if (vertexColors)
+ {
+ colors = new Color[vertsWide * vertsHigh];
+ }
}
//Add the triangle and return the next index
@@ -82,6 +106,12 @@ public Mesh CreateMesh()
triangles = triangles,
uv = uv
};
+
+ if (colors != null)
+ {
+ mesh.colors = colors;
+ }
+
mesh.RecalculateNormals();
return mesh;
}
diff --git a/Runtime/Utility/TextureScale.cs b/Runtime/Utility/TextureScale.cs
new file mode 100644
index 0000000..f779fa1
--- /dev/null
+++ b/Runtime/Utility/TextureScale.cs
@@ -0,0 +1,141 @@
+using System.Collections.Generic;
+using UnityEngine;
+using System.Threading.Tasks;
+
+namespace Gameframe.Procgen
+{
+ // Only works on ARGB32, RGB24 and Alpha8 textures that are marked readable
+ public static class TextureScale
+ {
+ public class TaskData
+ {
+ public int start;
+ public int end;
+
+ public TaskData(int s, int e)
+ {
+ start = s;
+ end = e;
+ }
+ }
+
+ public static async Task PointAsync(Texture2D tex, int newWidth, int newHeight)
+ {
+ await ThreadedScaleAsync(tex, newWidth, newHeight, false);
+ }
+
+ public static async Task BilinearAsync(Texture2D tex, int newWidth, int newHeight)
+ {
+ await ThreadedScaleAsync(tex, newWidth, newHeight, true);
+ }
+
+ private static async Task ThreadedScaleAsync(Texture2D tex, int newWidth, int newHeight, bool useBilinear)
+ {
+ var texColors = tex.GetPixels();
+ var newColors = new Color[newWidth * newHeight];
+
+ float ratioX;
+ float ratioY;
+ if (useBilinear)
+ {
+ ratioX = 1.0f / ((float) newWidth / (tex.width - 1));
+ ratioY = 1.0f / ((float) newHeight / (tex.height - 1));
+ }
+ else
+ {
+ ratioX = ((float) tex.width) / newWidth;
+ ratioY = ((float) tex.height) / newHeight;
+ }
+
+ var width = tex.width;
+
+ var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
+ var slice = newHeight / cores;
+
+ var tasks = new List();
+
+ if (cores > 1)
+ {
+ for (var i = 0; i < cores; i++)
+ {
+ var taskData = new TaskData(slice * i, slice * (i + 1));
+ var task = Task.Run(() =>
+ {
+ if (useBilinear)
+ {
+ BilinearScale(taskData,texColors,newColors,width,newWidth,ratioX,ratioY);
+ }
+ else
+ {
+ PointScale(taskData,texColors,newColors,width,newWidth,ratioX,ratioY);
+ }
+ });
+ tasks.Add(task);
+ }
+ await Task.WhenAll(tasks);
+ }
+ else
+ {
+ var taskData = new TaskData(0, newHeight);
+ await Task.Run(() =>
+ {
+ if (useBilinear)
+ {
+ BilinearScale(taskData,texColors,newColors,width,newWidth,ratioX,ratioY);
+ }
+ else
+ {
+ PointScale(taskData,texColors,newColors,width,newWidth,ratioX,ratioY);
+ }
+ });
+ }
+
+ tex.Resize(newWidth, newHeight);
+ tex.SetPixels(newColors);
+ tex.Apply();
+ }
+
+ private static void BilinearScale(TaskData taskData, Color[] texColors, Color[] newColors, int width, int newWidth, float ratioX, float ratioY)
+ {
+ for (var y = taskData.start; y < taskData.end; y++)
+ {
+ int yFloor = (int) Mathf.Floor(y * ratioY);
+ var y1 = yFloor * width;
+ var y2 = (yFloor + 1) * width;
+ var yw = y * newWidth;
+
+ for (var x = 0; x < newWidth; x++)
+ {
+ int xFloor = (int) Mathf.Floor(x * ratioX);
+ var xLerp = x * ratioX - xFloor;
+ newColors[yw + x] = ColorLerpUnclamped(
+ ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor + 1], xLerp),
+ ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor + 1], xLerp),
+ y * ratioY - yFloor);
+ }
+ }
+ }
+
+ private static void PointScale(TaskData taskData, Color[] texColors, Color[] newColors, int width, int newWidth, float ratioX, float ratioY)
+ {
+ for (var y = taskData.start; y < taskData.end; y++)
+ {
+ var thisY = (int) (ratioY * y) * width;
+ var yw = y * newWidth;
+ for (var x = 0; x < newWidth; x++)
+ {
+ newColors[yw + x] = texColors[(int) (thisY + ratioX * x)];
+ }
+ }
+ }
+
+ private static Color ColorLerpUnclamped(Color c1, Color c2, float value)
+ {
+ return new Color(c1.r + (c2.r - c1.r) * value,
+ c1.g + (c2.g - c1.g) * value,
+ c1.b + (c2.b - c1.b) * value,
+ c1.a + (c2.a - c1.a) * value);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Utility/TextureScale.cs.meta b/Runtime/Utility/TextureScale.cs.meta
new file mode 100644
index 0000000..6ccdaab
--- /dev/null
+++ b/Runtime/Utility/TextureScale.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b537ab97a9076f14ab8b3903b75a6f15
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Utility/VoxelMeshUtility.cs b/Runtime/Utility/VoxelMeshUtility.cs
index 993e29a..23eb3ee 100644
--- a/Runtime/Utility/VoxelMeshUtility.cs
+++ b/Runtime/Utility/VoxelMeshUtility.cs
@@ -31,42 +31,42 @@ public static VoxelMeshData CreateMeshData(float[,] noiseMap, int chunkX, int ch
var right = mapX + 1 < width ? terrainMap[mapX + 1, mapY] : null;
var left = mapX - 1 >= 0 ? terrainMap[mapX - 1, mapY] : null;
- meshData.AddUpQuad(x, y, terrain.Elevation);
+ meshData.AddUpQuad(x, y, terrain.MinElevation);
- if (left != null && left.Elevation < terrain.Elevation)
+ if (left != null && left.MinElevation < terrain.MinElevation)
{
- meshData.AddLeftQuad(x, y, terrain.Elevation, terrain.Elevation - left.Elevation);
+ meshData.AddLeftQuad(x, y, terrain.MinElevation, terrain.MinElevation - left.MinElevation);
}
else if (edges && mapX - 1 < 0)
{
- meshData.AddLeftQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddLeftQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (front != null && front.Elevation < terrain.Elevation)
+ if (front != null && front.MinElevation < terrain.MinElevation)
{
- meshData.AddFrontQuad(x, y, terrain.Elevation, terrain.Elevation - front.Elevation);
+ meshData.AddFrontQuad(x, y, terrain.MinElevation, terrain.MinElevation - front.MinElevation);
}
else if (edges && mapY + 1 >= height)
{
- meshData.AddFrontQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddFrontQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (right != null && right.Elevation < terrain.Elevation)
+ if (right != null && right.MinElevation < terrain.MinElevation)
{
- meshData.AddRightQuad(x, y, terrain.Elevation, terrain.Elevation - right.Elevation);
+ meshData.AddRightQuad(x, y, terrain.MinElevation, terrain.MinElevation - right.MinElevation);
}
else if (edges && mapX + 1 >= width)
{
- meshData.AddRightQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddRightQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (back != null && back.Elevation < terrain.Elevation)
+ if (back != null && back.MinElevation < terrain.MinElevation)
{
- meshData.AddBackQuad(x, y, terrain.Elevation, terrain.Elevation - back.Elevation);
+ meshData.AddBackQuad(x, y, terrain.MinElevation, terrain.MinElevation - back.MinElevation);
}
else if (edges && mapY - 1 < 0)
{
- meshData.AddBackQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddBackQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
}
}
@@ -98,42 +98,42 @@ public static VoxelMeshData CreateMeshData(float[] heightMap, int width, int hei
var right = mapX + 1 < width ? terrainMap[mapY * width + mapX + 1] : null;
var left = mapX - 1 >= 0 ? terrainMap[mapY * width + mapX - 1] : null;
- meshData.AddUpQuad(x, y, terrain.Elevation);
+ meshData.AddUpQuad(x, y, terrain.MinElevation);
- if (left != null && left.Elevation < terrain.Elevation)
+ if (left != null && left.MinElevation < terrain.MinElevation)
{
- meshData.AddLeftQuad(x, y, terrain.Elevation, terrain.Elevation - left.Elevation);
+ meshData.AddLeftQuad(x, y, terrain.MinElevation, terrain.MinElevation - left.MinElevation);
}
else if (edges && mapX - 1 < 0)
{
- meshData.AddLeftQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddLeftQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (front != null && front.Elevation < terrain.Elevation)
+ if (front != null && front.MinElevation < terrain.MinElevation)
{
- meshData.AddFrontQuad(x, y, terrain.Elevation, terrain.Elevation - front.Elevation);
+ meshData.AddFrontQuad(x, y, terrain.MinElevation, terrain.MinElevation - front.MinElevation);
}
else if (edges && mapY + 1 >= height)
{
- meshData.AddFrontQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddFrontQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (right != null && right.Elevation < terrain.Elevation)
+ if (right != null && right.MinElevation < terrain.MinElevation)
{
- meshData.AddRightQuad(x, y, terrain.Elevation, terrain.Elevation - right.Elevation);
+ meshData.AddRightQuad(x, y, terrain.MinElevation, terrain.MinElevation - right.MinElevation);
}
else if (edges && mapX + 1 >= width)
{
- meshData.AddRightQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddRightQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
- if (back != null && back.Elevation < terrain.Elevation)
+ if (back != null && back.MinElevation < terrain.MinElevation)
{
- meshData.AddBackQuad(x, y, terrain.Elevation, terrain.Elevation - back.Elevation);
+ meshData.AddBackQuad(x, y, terrain.MinElevation, terrain.MinElevation - back.MinElevation);
}
else if (edges && mapY - 1 < 0)
{
- meshData.AddBackQuad(x, y, terrain.Elevation, terrain.Elevation + edgeThickness);
+ meshData.AddBackQuad(x, y, terrain.MinElevation, terrain.MinElevation + edgeThickness);
}
}
}
diff --git a/Runtime/WorldMap/Layers/HeightMapLayerGenerator.cs b/Runtime/WorldMap/Layers/HeightMapLayerGenerator.cs
index f52ac14..fc5d64d 100644
--- a/Runtime/WorldMap/Layers/HeightMapLayerGenerator.cs
+++ b/Runtime/WorldMap/Layers/HeightMapLayerGenerator.cs
@@ -12,6 +12,10 @@ public enum MapType
Falloff,
NoiseWithFalloff
}
+
+ [SerializeField] private bool step = false;
+
+ [SerializeField] private int stepCount = 10;
[SerializeField] private Vector2 offset = Vector2.zero;
@@ -56,7 +60,14 @@ public HeightMapLayerData Generate(int width, int height, int seed)
{
for (int x = 0; x < width; x++)
{
- heightMap[y * width + x] = noiseMap[x, y];
+ var val = noiseMap[x, y];
+
+ if (step)
+ {
+ val = Mathf.RoundToInt(val * stepCount) / (float)stepCount;
+ }
+
+ heightMap[y * width + x] = val;
}
}
diff --git a/Runtime/WorldMap/Terrain/TerrainTable.cs b/Runtime/WorldMap/Terrain/TerrainTable.cs
index f544031..5234f62 100644
--- a/Runtime/WorldMap/Terrain/TerrainTable.cs
+++ b/Runtime/WorldMap/Terrain/TerrainTable.cs
@@ -16,7 +16,7 @@ public Color GetColor(float value)
{
if (value <= regions[i].Threshold)
{
- return regions[i].HighColor;
+ return regions[i].ColorGradient.Evaluate(1);
}
}
@@ -40,8 +40,8 @@ private Color GetGradiatedColor(float value)
public static Color GetGradiatedColor(TerrainType region, float value)
{
- var intensity = Mathf.InverseLerp(region.Threshold, region.Floor, value);
- return Color.Lerp(region.HighColor, region.LowColor, intensity);
+ var intensity = Mathf.InverseLerp(region.Floor, region.Threshold, value);
+ return region.ColorGradient.Evaluate(intensity);
}
public TerrainType GetTerrainType(float value)
@@ -86,7 +86,7 @@ public static Color[] GetColorMap(float[,] noiseMap, TerrainType[,] terrainMap,
for (int x = 0; x < width; x++)
{
var index = y * width + x;
- colorMap[index] = gradiate ? GetGradiatedColor(terrainMap[x, y], noiseMap[x, y]) : terrainMap[x, y].HighColor;
+ colorMap[index] = gradiate ? GetGradiatedColor(terrainMap[x, y], noiseMap[x, y]) : terrainMap[x, y].ColorGradient.Evaluate(1);
}
}
@@ -98,7 +98,7 @@ public static Color[] GetColorMap(float[] noiseMap, TerrainType[] terrainMap, bo
var colorMap = new Color[noiseMap.Length];
for (int i = 0; i < colorMap.Length; i++)
{
- colorMap[i] = gradiate ? GetGradiatedColor(terrainMap[i], noiseMap[i]) : terrainMap[i].HighColor;
+ colorMap[i] = gradiate ? GetGradiatedColor(terrainMap[i], noiseMap[i]) : terrainMap[i].ColorGradient.Evaluate(1);
}
return colorMap;
@@ -116,7 +116,7 @@ public static Color[] GetColorMap(float[,] noiseMap, TerrainType[] terrainMap, b
{
var index = y * width + x;
colorMap[index] =
- gradiate ? GetGradiatedColor(terrainMap[index], noiseMap[x, y]) : terrainMap[index].HighColor;
+ gradiate ? GetGradiatedColor(terrainMap[index], noiseMap[x, y]) : terrainMap[index].ColorGradient.Evaluate(1);
}
}
@@ -196,6 +196,16 @@ private void OnValidate()
{
regions[i].Floor = regions[i - 1].Threshold;
}
+
+ if (i > 0 && regions[i].MinElevation < regions[i - 1].MaxElevation)
+ {
+ regions[i].MinElevation = regions[i - 1].MaxElevation;
+ }
+
+ if (regions[i].MaxElevation < regions[i].MinElevation)
+ {
+ regions[i].MaxElevation = regions[i].MinElevation;
+ }
}
}
diff --git a/Runtime/WorldMap/Terrain/TerrainType.cs b/Runtime/WorldMap/Terrain/TerrainType.cs
index f97f0e1..28b66d1 100644
--- a/Runtime/WorldMap/Terrain/TerrainType.cs
+++ b/Runtime/WorldMap/Terrain/TerrainType.cs
@@ -34,15 +34,24 @@ public float Threshold
set => _threshold = value;
}
- [FormerlySerializedAs("_meshHeight")] [SerializeField]
- private float _elevation;
- public float Elevation => _elevation;
+ [FormerlySerializedAs("_elevation")] [SerializeField]
+ private float _minElevation;
+ public float MinElevation
+ {
+ get => _minElevation;
+ set => _minElevation = value;
+ }
- [SerializeField] private Color _lowColor = Color.black;
- public Color LowColor => _lowColor;
+ [SerializeField]
+ private float _maxElevation;
+ public float MaxElevation
+ {
+ get => _maxElevation;
+ set => _maxElevation = value;
+ }
- [FormerlySerializedAs("_color")] [SerializeField]
- private Color _highColor = Color.white;
- public Color HighColor => _highColor;
+ [SerializeField]
+ private Gradient gradient;
+ public Gradient ColorGradient => gradient;
}
}
\ No newline at end of file
diff --git a/Runtime/WorldMap/Views/WoldMapTerrainMeshView.cs b/Runtime/WorldMap/Views/WoldMapTerrainMeshView.cs
index 73c4040..bfb52e3 100644
--- a/Runtime/WorldMap/Views/WoldMapTerrainMeshView.cs
+++ b/Runtime/WorldMap/Views/WoldMapTerrainMeshView.cs
@@ -10,6 +10,14 @@ public class WoldMapTerrainMeshView : MonoBehaviour, IWorldMapView
[SerializeField] private MeshFilter _meshFilter = null;
[SerializeField, Range(0,6)] private int levelOfDetail;
+
+ [SerializeField] private float heightScale = 1;
+
+ [SerializeField] private TerrainTable terrainTable = null;
+
+ [SerializeField] private bool smooth = false;
+
+ [SerializeField] private bool useColorGradient = false;
//This is here just to get the enabled checkbox in editor
private void Start()
@@ -23,8 +31,39 @@ public void DisplayMap(WorldMapData worldMapData)
return;
}
var heightMap = worldMapData.GetLayer().heightMap;
- var meshData = TerrainMeshUtility.GenerateMesh(heightMap,worldMapData.width,worldMapData.height,levelOfDetail);
- _meshFilter.mesh = meshData.CreateMesh();
+
+ if (terrainTable == null)
+ {
+ var meshData = TerrainMeshUtility.GenerateMesh(heightMap,worldMapData.width,worldMapData.height,heightScale,levelOfDetail);
+ _meshFilter.mesh = meshData.CreateMesh();
+ }
+ else
+ {
+ var meshData = TerrainMeshUtility.GenerateMesh(heightMap,worldMapData.width,worldMapData.height,levelOfDetail,
+ x =>
+ {
+ var terrainType = terrainTable.GetTerrainType(x);
+ if (smooth)
+ {
+ var t = Mathf.InverseLerp(terrainType.Floor, terrainType.Threshold, x);
+ return Mathf.Lerp(terrainType.MinElevation, terrainType.MaxElevation, t) * heightScale;
+ }
+ return terrainTable.GetTerrainType(x).MinElevation * heightScale;
+ },
+ x =>
+ {
+ var terrainType = terrainTable.GetTerrainType(x);
+ if (!useColorGradient)
+ {
+ return terrainType.ColorGradient.Evaluate(0);
+ }
+ var t = Mathf.InverseLerp(terrainType.Floor, terrainType.Threshold, x);
+ return terrainType.ColorGradient.Evaluate(t);
+ });
+ _meshFilter.mesh = meshData.CreateMesh();
+ }
+
}
+
}
}
diff --git a/Runtime/WorldMap/Views/WorldMapBorderView.cs b/Runtime/WorldMap/Views/WorldMapBorderView.cs
new file mode 100644
index 0000000..4e88e7d
--- /dev/null
+++ b/Runtime/WorldMap/Views/WorldMapBorderView.cs
@@ -0,0 +1,142 @@
+using System.Collections.Generic;
+using System.Linq;
+using ICSharpCode.NRefactory.Ast;
+using UnityEngine;
+using UnityEngine.Serialization;
+
+namespace Gameframe.Procgen
+{
+ public class WorldMapBorderView : MonoBehaviour, IWorldMapView
+ {
+ [SerializeField]
+ private LineRenderer prefab = null;
+
+ [SerializeField]
+ private Vector3 offset;
+
+ [SerializeField]
+ private Color[] regionColors = new Color[0];
+
+ [FormerlySerializedAs("lines")] [SerializeField]
+ private List lineRenderers = new List();
+
+ [SerializeField] private int minLineLength = 2;
+
+ private void Start()
+ {
+ if (prefab != null)
+ {
+ prefab.gameObject.SetActive(false);
+ }
+ }
+
+ [ContextMenu("Clear Lines")]
+ public void ClearLines()
+ {
+ foreach (var line in lineRenderers)
+ {
+ if (Application.isPlaying)
+ {
+ Destroy(line.gameObject);
+ }
+ else
+ {
+ DestroyImmediate(line.gameObject);
+
+ }
+ }
+ lineRenderers.Clear();
+ }
+
+ public void DisplayMap(WorldMapData mapData)
+ {
+ if (!enabled || prefab == null)
+ {
+ return;
+ }
+
+ prefab.gameObject.SetActive(false);
+
+ ClearLines();
+
+ var positionOffset = new Vector3(mapData.width*-0.5f,0, mapData.height*0.5f) + offset;
+
+ var regionLayer = mapData.GetLayer();
+ foreach (var region in regionLayer.regions)
+ {
+ //Each region could have more than one border line to draw
+ //Border point list is unordered so we need to also figure out what the lines are
+
+ //Convert border points to 3D space
+ var points = new List(region.borderPoints.Select((pt) => new Vector3(pt.x,0,-pt.y) + positionOffset));
+
+ //Extract lines from list of points by getting closest points
+ var lines = new List>();
+ var currentLine = new List();
+ lines.Add(currentLine);
+ var currentPt = points[0];
+ points.RemoveAt(0);
+ while (points.Count > 0)
+ {
+ float minDistance = float.MaxValue;
+ int minIndex = -1;
+
+ for (int i = 0; i < points.Count; i++)
+ {
+ var distance = (currentPt - points[i]).sqrMagnitude;
+ if (distance < minDistance)
+ {
+ minDistance = distance;
+ minIndex = i;
+ }
+ }
+
+
+ if (minDistance > 2)
+ {
+ //Start a new line if the closest points was more than a certain distance away
+ lines.Add(currentLine);
+ currentLine = new List();
+ }
+
+ currentPt = points[minIndex];
+ currentLine.Add(points[minIndex]);
+ points.RemoveAt(minIndex);
+ }
+
+ var regionColor = regionColors.Length > 0 ? regionColors[(region.id - 1) % regionColors.Length] : Color.white;
+
+ foreach (var line in lines)
+ {
+ //Don't draw anything with less than 2 points
+ if (line.Count < minLineLength)
+ {
+ continue;
+ }
+
+ var lineRenderer = Instantiate(prefab, transform);
+ lineRenderer.transform.localEulerAngles = new Vector3(90,0,0);
+ lineRenderer.startColor = regionColor;
+ lineRenderer.endColor = regionColor;
+
+ //lineRenderer.positionCount = region.borderPoints.Count;
+ lineRenderer.positionCount = line.Count;
+ lineRenderer.SetPositions(line.ToArray());
+
+ var startPt = line[0];
+ var endPt = line[line.Count - 1];
+ //If the end is close enough to the start then complete the loop
+ if ((startPt - endPt).sqrMagnitude <= 2)
+ {
+ lineRenderer.loop = true;
+ }
+
+ lineRenderer.gameObject.SetActive(true);
+ lineRenderers.Add(lineRenderer);
+ }
+
+ }
+ }
+ }
+}
+
diff --git a/Runtime/WorldMap/Views/WorldMapBorderView.cs.meta b/Runtime/WorldMap/Views/WorldMapBorderView.cs.meta
new file mode 100644
index 0000000..e22306f
--- /dev/null
+++ b/Runtime/WorldMap/Views/WorldMapBorderView.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e5068605380f54a4392fe9a94c0c8f7b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/WorldMap/Views/WorldMapHexMeshView.cs b/Runtime/WorldMap/Views/WorldMapHexMeshView.cs
new file mode 100644
index 0000000..76acb55
--- /dev/null
+++ b/Runtime/WorldMap/Views/WorldMapHexMeshView.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Gameframe.Procgen
+{
+
+ public class WorldMapHexMeshView : MonoBehaviour, IWorldMapView
+ {
+ [SerializeField] private WorldMapViewChunk _prefab = null;
+ [SerializeField] private float radius = 1f;
+ [SerializeField] private TerrainTable terrainTable = null;
+ [SerializeField] private bool useColorGradient = false;
+ [SerializeField] private int chunkWidth = 16;
+ [SerializeField] private int chunkHeight = 16;
+ [SerializeField] private float heightScale = 1;
+ [SerializeField] private bool smooth = false;
+
+ [SerializeField, Range(0,1f)] private float border = 0.25f;
+
+ [SerializeField] private List chunkList = new List();
+ private readonly Dictionary _chunks = new Dictionary();
+
+ private void Start()
+ {
+ //This is here just to show the enable checkbox in editor
+ }
+
+ private void OnDisable()
+ {
+ ClearChunks();
+ }
+
+ public void DisplayMap(WorldMapData mapData)
+ {
+ if (!enabled)
+ {
+ return;
+ }
+
+ var heightMap = mapData.GetLayer().heightMap;
+
+ ClearChunks();
+
+ //Chunks
+ var chunksWide = Mathf.CeilToInt(mapData.width / (float)chunkWidth);
+ var chunksHigh = Mathf.CeilToInt(mapData.height / (float)chunkHeight);
+
+ for (var chunkY = 0; chunkY < chunksHigh; chunkY++)
+ {
+ for (var chunkX = 0; chunkX < chunksWide; chunkX++)
+ {
+ //Create the mesh
+ var startX = chunkX * chunkWidth;
+ var startY = chunkY * chunkHeight;
+ var chunkView = GetChunk(new Vector2Int(chunkX,chunkY));
+ chunkView.transform.localPosition = new Vector3(0,0,0);
+ var mesh = HexMeshUtility.GenerateHexagonMesh(radius, border, startX, startY, chunkWidth, chunkHeight, mapData.width, mapData.height, heightMap, GetColor, GetElevation);
+ chunkView.SetMesh(mesh);
+ }
+ }
+ }
+
+ private Color GetColor(float height)
+ {
+ if (terrainTable == null)
+ {
+ return Color.white;
+ }
+
+ var terrainType = terrainTable.GetTerrainType(height);
+ if (!useColorGradient)
+ {
+ return terrainType.ColorGradient.Evaluate(0);
+ }
+
+ var t = Mathf.InverseLerp(terrainType.Floor, terrainType.Threshold, height);
+ return terrainType.ColorGradient.Evaluate(t);
+ }
+
+ private float GetElevation(float height)
+ {
+ var terrainType = terrainTable.GetTerrainType(height);
+ if (smooth)
+ {
+ var t = Mathf.InverseLerp(terrainType.Floor, terrainType.Threshold, height);
+ return Mathf.Lerp(terrainType.MinElevation, terrainType.MaxElevation, t) * heightScale;
+ }
+ return terrainTable.GetTerrainType(height).MinElevation * heightScale;
+ }
+
+ private WorldMapViewChunk GetChunk(Vector2Int chunkPt)
+ {
+ WorldMapViewChunk chunk = null;
+ if (_chunks.TryGetValue(chunkPt, out chunk))
+ {
+ return chunk;
+ }
+
+ //Create a new chunk
+ chunk = Instantiate(_prefab,transform);
+ _chunks.Add(chunkPt, chunk);
+ chunkList.Add(chunk);
+ return chunk;
+ }
+
+ [ContextMenu("Clear Chunks")]
+ public void ClearChunks()
+ {
+ foreach (var chunk in chunkList)
+ {
+ if (chunk == null)
+ {
+ continue;
+ }
+
+ if (Application.isEditor)
+ {
+ DestroyImmediate(chunk.gameObject);
+ }
+ else
+ {
+ Destroy(chunk.gameObject);
+ }
+ }
+
+ chunkList.Clear();
+ _chunks.Clear();
+ }
+
+ }
+
+}
+
diff --git a/Runtime/WorldMap/Views/WorldMapHexMeshView.cs.meta b/Runtime/WorldMap/Views/WorldMapHexMeshView.cs.meta
new file mode 100644
index 0000000..bcd47d2
--- /dev/null
+++ b/Runtime/WorldMap/Views/WorldMapHexMeshView.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 048b34f00c228f94fbd7154e0145d6f8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/WorldMap/Views/WorldMapTextureView.cs b/Runtime/WorldMap/Views/WorldMapTextureView.cs
index 9b9b53c..92a7a5f 100644
--- a/Runtime/WorldMap/Views/WorldMapTextureView.cs
+++ b/Runtime/WorldMap/Views/WorldMapTextureView.cs
@@ -4,14 +4,12 @@ namespace Gameframe.Procgen
{
public class WorldMapTextureView : MonoBehaviour, IWorldMapView
{
- [SerializeField] private Renderer _renderer = null;
+ [SerializeField] private Material _material = null;
[SerializeField] private bool mainTexture = false;
[SerializeField] private string texturePropertyName = "_BaseMap";
[SerializeField] private TerrainTable _terrainTable = null;
-
- [SerializeField] private bool scaleRenderer = false;
-
+
[SerializeField] private bool gradiate = false;
[SerializeField] private bool fillRegions = false;
@@ -24,8 +22,21 @@ public class WorldMapTextureView : MonoBehaviour, IWorldMapView
[SerializeField] private Color[] regionColors = new Color[0];
[SerializeField] private FilterMode filterMode = FilterMode.Point;
- public void DisplayMap(WorldMapData worldMapData)
+ [SerializeField] private bool scaleTexture = false;
+ [SerializeField] private float textureScale = 2f;
+
+ private void Start()
{
+ //This is here just to show the enabled checkbox in the unity inspector
+ }
+
+ public async void DisplayMap(WorldMapData worldMapData)
+ {
+ if (!enabled)
+ {
+ return;
+ }
+
var heightMapLayer = worldMapData.GetLayer();
var regionMapLayer = worldMapData.GetLayer();
@@ -98,9 +109,9 @@ public void DisplayMap(WorldMapData worldMapData)
texture.filterMode = filterMode;
SetTexture(texture);
- if (scaleRenderer)
+ if (scaleTexture)
{
- _renderer.transform.localScale = new Vector3(width, height, 1);
+ await TextureScale.BilinearAsync(texture, Mathf.Min(2048,Mathf.RoundToInt(width * textureScale)), Mathf.Min(2048,Mathf.RoundToInt(height * textureScale)));
}
}
@@ -108,11 +119,11 @@ private void SetTexture(Texture2D texture)
{
if (!mainTexture)
{
- _renderer.sharedMaterial.SetTexture(texturePropertyName, texture);
+ _material.SetTexture(texturePropertyName, texture);
}
else
{
- _renderer.sharedMaterial.mainTexture = texture;
+ _material.mainTexture = texture;
}
}
diff --git a/Runtime/WorldMap/WorldMapGenController.cs b/Runtime/WorldMap/WorldMapGenController.cs
index 0a9dea0..241cac3 100644
--- a/Runtime/WorldMap/WorldMapGenController.cs
+++ b/Runtime/WorldMap/WorldMapGenController.cs
@@ -1,7 +1,9 @@
//Ignore those dumb 'never assigned to' warnings cuz this is Unity and our fields are serialized
#pragma warning disable CS0649
+using System;
using UnityEngine;
+using Random = UnityEngine.Random;
namespace Gameframe.Procgen
{
@@ -11,6 +13,8 @@ public class WorldMapGenController : MonoBehaviour
[SerializeField] private int seed = 100;
+ [SerializeField] private bool randomizeSeed = false;
+
[SerializeField, HideInInspector] private WorldMapData _mapData;
private void Start()
@@ -21,6 +25,10 @@ private void Start()
[ContextMenu("GenerateMap")]
public void GenerateMap()
{
+ if (randomizeSeed)
+ {
+ seed = Random.Range(int.MinValue, Int32.MaxValue);
+ }
_mapData = _generator.GenerateMap(seed);
DisplayMap(_mapData);
}
diff --git a/package.json b/package.json
index 0a9e1cb..07494c4 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"name": "com.gameframe.procgen",
"displayName": "Gameframe.Procgen",
"repositoryName": "UnityProcgen",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "Library of utilitities for procedural generation",
"type": "library",
"keywords": [],