using UnityEngine; using UnityEditor; using InfinityCode.RealWorldTerrain; public class CreateRWTTerrainBaseboards : ScriptableWizard { public RealWorldTerrainContainer container; public float globalH = -40.0f; public Color selectColor = Color.white; public float UVFactorX = 8.0f; public float UVFactorZ = 8.0f; public Texture selectTexture; private Vector3[] vertices; private Vector2[] uvs; private Vector3[] normals; private int[] triangles; private int heightmapResolution; [MenuItem("Window/Infinity Code/Real World Terrain/Extensions/Create RWT Terrains Baseboards...")] static void CreateWizard() { CreateRWTTerrainBaseboards wizard = DisplayWizard("Create RWT Terrains Baseboards", typeof(CreateRWTTerrainBaseboards)) as CreateRWTTerrainBaseboards; wizard.container = FindObjectOfType(); } void OnWizardCreate() { if (container == null) container = FindObjectOfType(); if (container == null) return; if (container.prefs.resultType != RealWorldTerrainResultType.terrain) return; Material mat = new Material(Shader.Find("Diffuse")); mat.color = selectColor; mat.mainTexture = selectTexture; mat.name = "BaseboardsMaterial"; RealWorldTerrainVector2i count = container.terrainCount; RealWorldTerrainItem[] terrains = container.terrains; heightmapResolution = container.prefs.heightmapResolution; int countVertices = heightmapResolution * 2; vertices = new Vector3[countVertices]; normals = new Vector3[countVertices]; uvs = new Vector2[countVertices]; triangles = new int[(heightmapResolution - 1) * 6]; for (int x = 0; x < count.x; x++) { bool left = x == 0; bool right = x == count.x - 1; for (int z = 0; z < count.y; z++) { bool top = z == 0; bool bottom = z == count.y - 1; RealWorldTerrainItem item = terrains[z * count.x + x]; CreateBorder(item, mat, left, right, top, bottom); } } } private void CreateBorder(RealWorldTerrainItem item, Material mat, bool left, bool right, bool top, bool bottom) { TerrainData terrainData = item.terrainData; float heightScale = terrainData.size.y; float maxHeight = float.MinValue; if (left) { float[,] heights = terrainData.GetHeights(0, 0, 1, heightmapResolution); float scale = terrainData.size.z / (heightmapResolution - 1); float x = 0; for (int i = 0; i < heightmapResolution; i++) { float h = heights[i, 0] * heightScale; if (h > maxHeight) maxHeight = h; vertices[i] = new Vector3(x, h, i * scale); } CreateMesh(item, mat, "Left Border", Vector3.left, maxHeight, UVFactorX, false); } if (right) { float[,] heights = terrainData.GetHeights(heightmapResolution - 1, 0, 1, heightmapResolution); float scale = terrainData.size.z / (heightmapResolution - 1); float x = terrainData.size.x; for (int i = 0; i < heightmapResolution; i++) { float h = heights[i, 0] * heightScale; if (h > maxHeight) maxHeight = h; vertices[i] = new Vector3(x, h, i * scale); } CreateMesh(item, mat, "Right Border", Vector3.right, maxHeight, UVFactorX, true); } if (top) { float[,] heights = terrainData.GetHeights(0, 0, heightmapResolution, 1); float scale = terrainData.size.x / (heightmapResolution - 1); float z = 0; for (int i = 0; i < heightmapResolution; i++) { float h = heights[0, i] * heightScale; if (h > maxHeight) maxHeight = h; vertices[i] = new Vector3(i * scale, h, z); } CreateMesh(item, mat, "Top Border", Vector3.forward, maxHeight, UVFactorZ, true); } if (bottom) { float[,] heights = terrainData.GetHeights(0, heightmapResolution - 1, heightmapResolution, 1); float scale = terrainData.size.x / (heightmapResolution - 1); float z = terrainData.size.z; for (int i = 0; i < heightmapResolution; i++) { float h = heights[0, i] * heightScale; if (h > maxHeight) maxHeight = h; vertices[i] = new Vector3(i * scale, h, z); } CreateMesh(item, mat, "Bottom Border", Vector3.back, maxHeight, UVFactorZ, false); } } private void CreateMesh(RealWorldTerrainItem item, Material mat, string goName, Vector3 normalDirection, float maxHeight, float UVFactor, bool forwardTriangleOrder) { int ti = 0; for (int i = 0; i < heightmapResolution; i++) { int i2 = i + heightmapResolution; Vector3 v = vertices[i]; float h = v.y; vertices[i2] = v; vertices[i2].y = globalH; float uvx = i / (float)heightmapResolution * UVFactor; uvs[i] = new Vector2(uvx, (h - globalH) / (maxHeight - globalH)); uvs[i2] = new Vector2(uvx, 0); normals[i] = normalDirection; normals[i2] = normalDirection; if (i < heightmapResolution - 1) { triangles[ti++] = i; if (forwardTriangleOrder) { triangles[ti++] = i + 1; triangles[ti++] = i2 + 1; } else { triangles[ti++] = i2 + 1; triangles[ti++] = i + 1; } triangles[ti++] = i; if (forwardTriangleOrder) { triangles[ti++] = i2 + 1; triangles[ti++] = i2; } else { triangles[ti++] = i2; triangles[ti++] = i2 + 1; } } } Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.normals = normals; mesh.uv = uvs; mesh.triangles = triangles; mesh.RecalculateBounds(); GameObject go = new GameObject(goName); go.transform.parent = item.transform; go.transform.localPosition = Vector3.zero; MeshRenderer renderer = go.AddComponent(); renderer.sharedMaterial = mat; MeshFilter meshFilter = go.AddComponent(); meshFilter.sharedMesh = mesh; } }