public void Refresh() { if (points.Count < 2) { return; } transform.localScale = Vector3.one; if (!gameObject.GetComponent <MeshFilter>()) { gameObject.AddComponent <MeshFilter>(); } else { if (gameObject.GetComponent <MeshFilter>().sharedMesh != null) { DestroyImmediate(gameObject.GetComponent <MeshFilter>().sharedMesh); } } if (!gameObject.GetComponent <MeshRenderer>()) { gameObject.AddComponent <MeshRenderer>(); } List <Vector3> v = new List <Vector3>(); List <int> t = new List <int>(); // calculate angles for each line segment, then build out a plane for it int tri_index = 0; int segments = connectEnds ? points.Count : points.Count - 1; theta = new float[segments]; for (int i = 0; i < segments; i++) { Vector2 a = points[i + 0].ToXZVector2(); Vector2 b = (connectEnds && i == segments - 1) ? points[0].ToXZVector2() : points[i + 1].ToXZVector2(); bool flip = (a.x > b.x); // ? theta[i] : -theta[i]; Vector3 rght = flip ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1); Vector3 lft = flip ? new Vector3(0, 0, 1) : new Vector3(0, 0, -1); theta[i] = MathExtensions.AngleRadian(a, b); // seg a v.Add(points[i] + rght * roadWidth); v.Add(points[i] + lft * roadWidth); // seg b int u = (connectEnds && i == segments - 1) ? 0 : i + 1; v.Add(points[u] + rght * roadWidth); v.Add(points[u] + lft * roadWidth); // apply angular rotation to points int l = v.Count - 4; v[l + 0] = v[l + 0].RotateAroundPoint(points[i + 0], -theta[i]); v[l + 1] = v[l + 1].RotateAroundPoint(points[i + 0], -theta[i]); v[l + 2] = v[l + 2].RotateAroundPoint(points[u], -theta[i]); v[l + 3] = v[l + 3].RotateAroundPoint(points[u], -theta[i]); t.AddRange(new int[6] { tri_index + 2, tri_index + 1, tri_index + 0, tri_index + 2, tri_index + 3, tri_index + 1 }); tri_index += 4; } // join edge vertices if (points.Count > 2) { segments = connectEnds ? v.Count : v.Count - 4; for (int i = 0; i < segments; i += 4) { int p4 = (connectEnds && i == segments - 4) ? 0 : i + 4; int p5 = (connectEnds && i == segments - 4) ? 1 : i + 5; int p6 = (connectEnds && i == segments - 4) ? 2 : i + 6; int p7 = (connectEnds && i == segments - 4) ? 3 : i + 7; Vector2 leftIntercept = MathExtensions.InterceptPoint( v[i + 0].ToXZVector2(), v[i + 2].ToXZVector2(), v[p4].ToXZVector2(), v[p6].ToXZVector2()); Vector2 rightIntercept = MathExtensions.InterceptPoint( v[i + 1].ToXZVector2(), v[i + 3].ToXZVector2(), v[p5].ToXZVector2(), v[p7].ToXZVector2()); v[i + 2] = leftIntercept.ToVector3(); v[p4] = leftIntercept.ToVector3(); v[i + 3] = rightIntercept.ToVector3(); v[p5] = rightIntercept.ToVector3(); } } transform.position = Vector3.zero; // // center pivot point and set height offset Vector3 cen = v.Average(); Vector3 diff = cen - transform.position; transform.position = cen; for (int i = 0; i < v.Count; i++) { v[i] = new Vector3(v[i].x, GroundHeight(v[i]) + groundOffset, v[i].z); v[i] -= diff; } Mesh m = new Mesh(); m.vertices = v.ToArray(); m.triangles = t.ToArray(); m.uv = CalculateUV(m.vertices); m.RecalculateNormals(); gameObject.GetComponent <MeshFilter>().sharedMesh = m; gameObject.GetComponent <MeshRenderer>().sharedMaterial = mat; #if UNITY_EDITOR Unwrapping.GenerateSecondaryUVSet(gameObject.GetComponent <MeshFilter>().sharedMesh); #endif }