public void GenerateTerrain() { GetHills(); GetTerrain(); if (alignHills) { AutoAlignHills(); } foreach (var terr in terrains) { Vector3 center = terr.GetComponent <Transform>().position; float[,] tab = new float[terr.terrainData.heightmapResolution, terr.terrainData.heightmapResolution]; float[,] coeffs = new float[terr.terrainData.heightmapResolution, terr.terrainData.heightmapResolution]; // bool[,] insideHill = new bool[terr.terrainData.heightmapResolution, terr.terrainData.heightmapResolution]; for (int i = 0; i < terr.terrainData.heightmapResolution; i++) { for (int j = 0; j < terr.terrainData.heightmapResolution; j++) { float x = (float)(j) / (terr.terrainData.heightmapResolution - 1) * (terr.terrainData.size.x) + center.x; float z = (float)(i) / (terr.terrainData.heightmapResolution - 1) * (terr.terrainData.size.z) + center.z; coeffs[i, j] = 2; // int hillsCount = 0; // float terrainHeight = 0; for (int ii = 0; ii < hills.Count; ii++) { Transform hillTransform = hills[ii].GetComponent <Transform>(); Hill hill = hillsList[ii]; float inrunTerrain = hills[ii].inrunTerrain; Vector3 pointOnHill = hillTransform.InverseTransformPoint(new Vector3(x, 0, z)); float hillY = 0; float b = 15; float c = 0; if (pointOnHill.x < hill.A.x) { c = hill.A.x + inrunFlatLength - pointOnHill.x; hillY = hill.A.y * inrunTerrain - hill.s; b = hill.b1 / 2; } else if (pointOnHill.x < hill.T.x) { hillY = hill.Inrun(pointOnHill.x) * inrunTerrain - hill.s; if (hill.A.x <= pointOnHill.x) { b = hill.bK; } b = Mathf.Lerp(hill.b2, hill.b1, pointOnHill.x / hill.A.x) / 2; } else if (hill.T.x <= pointOnHill.x && pointOnHill.x <= hill.U.x) { hillY = hill.LandingArea(pointOnHill.x); b = (pointOnHill.x <= hill.K.x ? (hill.b2 / 2) + pointOnHill.x / hill.K.x * ((hill.bK - hill.b2) / 2) : pointOnHill.x >= hill.U.x ? (hill.bU / 2) : (hill.bK / 2) + (pointOnHill.x - hill.K.x) / (hill.U.x - hill.K.x) * ((hill.bU - hill.bK) / 2)); } else if (pointOnHill.x <= hill.U.x + hill.a) { hillY = hill.U.y; b = hill.bU / 2; } else { c = pointOnHill.x - hill.U.x - hill.a; hillY = hill.U.y; } hillY += hillTransform.position.y; // float terrainY = 200 * Mathf.PerlinNoise(x / 200.0f + 2000, z / 200.0f + 2000); float terrainY = hill.U.y + hillTransform.GetComponent <Transform>().position.y; if (terrainBase == TerrainBase.PerlinNoise) { terrainY = 200 * Mathf.PerlinNoise(x / 200.0f + 2000, z / 200.0f + 2000); } else if (terrainBase == TerrainBase.currentTerrain) { terrainY = terr.terrainData.GetHeight(j, i) + center.y; // terrainY = coeffs[i, j] + center.y; } float blendFactor = Mathf.SmoothStep(0, 1, Mathf.Clamp01(new Vector2(Mathf.Clamp01((Mathf.Abs(pointOnHill.z) - b) / offset), Mathf.Clamp01(c / offset)).magnitude)); // float blendFactor = Mathf.Clamp01(new Vector2(Mathf.Clamp01((Mathf.Abs(pointOnHill.z) - b) / offset), Mathf.Clamp01(c / offset)).magnitude); float y = hillY * (1 - blendFactor) + terrainY * blendFactor; y = (y - center.y - 1) / terr.terrainData.size.y; if (blendFactor < coeffs[i, j]) { coeffs[i, j] = blendFactor; tab[i, j] = y; } // if (insideHill[i, j] == false) { tab[i, j] = y; } // if (blendFactor == 0) { insideHill[i, j] = true; } } } } terr.terrainData.SetHeights(0, 0, tab); } }
public void GenerateMesh() { hill.SetValues(profileData.Value); inrunTerrain = profileData.Value.terrainSteepness; generateGateStairsL = profileData.Value.gateStairsLeft; generateGateStairsR = profileData.Value.gateStairsRight; generateInrunStairsL = profileData.Value.inrunStairsLeft; generateInrunStairsR = profileData.Value.inrunStairsRight; inrunStairsAngle = profileData.Value.inrunStairsAngle; GenerateInrunCollider(); GenerateInrunTrack(); GenerateLandingAreaCollider(); GenerateLandingArea(); GenerateGateStairs(gateStairsL, 0, generateGateStairsL); GenerateGateStairs(gateStairsR, 1, generateGateStairsR); var stepsCount = Mathf.RoundToInt((hill.A.y - hill.T.y) / inrunStairsStepHeight); inrunStairsStepHeight = (hill.A.y - hill.T.y) / stepsCount; GenerateInrunStairs(inrunStairsL, 0, generateInrunStairsL, generateGateStairsL, stepsCount); GenerateInrunStairs(inrunStairsR, 1, generateInrunStairsR, generateGateStairsR, stepsCount); GenerateLandingAreaGuardrail(landingAreaGuardrailL, 0, generateLandingAreaGuardrailL); GenerateLandingAreaGuardrail(landingAreaGuardrailR, 1, generateLandingAreaGuardrailR); GenerateInrunGuardrail(inrunGuardrailL, 0, true); GenerateInrunGuardrail(inrunGuardrailR, 1, true); GenerateInrunOuterGuardrail(inrunOuterGuardrailL, 0, true, generateGateStairsL); GenerateInrunOuterGuardrail(inrunOuterGuardrailR, 1, true, generateGateStairsR); GenerateInrunConstruction(); GenerateMarks(); if (generateTerrain) { // Debug.Log("GENERATING TERRAIN"); GetTerrain(); // Transform hillTransform = GetComponent<Transform>().transform; const float offset = 300f; const float inrunFlatLength = 5f; //Terrain foreach (var terr in terrains) { var center = terr.GetComponent <Transform>().position; var tab = new float[terr.terrainData.heightmapResolution, terr.terrainData.heightmapResolution]; for (var i = 0; i < terr.terrainData.heightmapResolution; i++) { for (var j = 0; j < terr.terrainData.heightmapResolution; j++) { var x = (float)(j) / (terr.terrainData.heightmapResolution - 1) * (terr.terrainData.size.x) + center.x; var z = (float)(i) / (terr.terrainData.heightmapResolution - 1) * (terr.terrainData.size.z) + center.z; float hillY = 0; float b = 15; float c = 0; if (x < hill.A.x) { c = hill.A.x + inrunFlatLength - x; hillY = hill.A.y * inrunTerrain - hill.s; } else if (x < hill.T.x) { hillY = hill.Inrun(x) * inrunTerrain - hill.s; if (hill.A.x <= x) { b = 15; } } else if (hill.T.x <= x && x <= hill.U.x) { hillY = hill.LandingArea(x); b = 15; } else if (x <= hill.U.x + hill.a) { hillY = hill.U.y; b = 15; } else { c = x - hill.U.x - hill.a; hillY = hill.U.y; } // float terrainY = 200 * Mathf.PerlinNoise(x / 200.0f + 2000, z / 200.0f + 2000); var terrainY = hill.U.y; if (terrainBase == TerrainBase.PerlinNoise) { terrainY = 200 * Mathf.PerlinNoise(x / 200.0f + 2000, z / 200.0f + 2000); } else if (terrainBase == TerrainBase.currentTerrain) { terrainY = terr.terrainData.GetHeight(j, i) + center.y; } var blendFactor = Mathf.SmoothStep(0, 1, Mathf.Clamp01(new Vector2(Mathf.Clamp01((Mathf.Abs(z) - b) / offset), Mathf.Clamp01(c / offset)).magnitude)); var y = hillY * (1 - blendFactor) + terrainY * blendFactor; // y += (Mathf.Abs((Mathf.Abs(z) - b)) <= 50 ? 2 * Mathf.Abs((Mathf.Abs(z) - b)) : 100) * 0.5f); y = (y - center.y - 1) / terr.terrainData.size.y; // if (i == 200 && j == 200) Debug.Log(x + " " + y); // Debug.Log(x + " " + y); tab[i, j] = Mathf.Clamp(y, 0, 1); } } terr.terrainData.SetHeights(0, 0, tab); } } if (saveMesh) { SaveMesh(inrun.gObj, "Inrun", true); SaveMesh(inrun.gObj, "InrunTrack"); SaveMesh(landingArea.gObj, "LandingAreaCollider", true); SaveMesh(landingArea.gObj, "LandingArea"); SaveMesh(gateStairsL.gObj, "GateStairsL"); SaveMesh(gateStairsR.gObj, "GateStairsR"); SaveMesh(inrunStairsL.gObj, "InrunStairsL"); SaveMesh(inrunStairsR.gObj, "InrunStairsR"); SaveMesh(landingAreaGuardrailL.gObj, "LandingAreaGuardrailL"); SaveMesh(landingAreaGuardrailR.gObj, "LandingAreaGuardrailR"); SaveMesh(inrunConstruction.gObj, "InrunConstruction"); SaveMesh(digitsMarks.gObj, "DigitsMarks"); } SetGate(hill, 1); DestroyLamps(); if (time == 0) { sunLight.intensity = 0.1f; RenderSettings.skybox = nightSkybox; GenerateLamps(); } else if (time == 1) { sunLight.intensity = 1f; RenderSettings.skybox = daySkybox; } }