private Mesh GeneratePathMesh(PathData path) { Shape section; if (_crossSectionAsset != null) { section = _crossSectionAsset.shape; } else { section = Shape.defaultShape; } int sectionVertexCount = section.PointCount; if (sectionVertexCount < 2) { //Debug.LogWarning("Path cannot being generated, minimum 2 points are required"); return(new Mesh()); } int points = path.Length + (_loopCurve ? 1 : 0); Vector3[] vertices = new Vector3[sectionVertexCount * (points + (_subdivisions - 1) * (points - 1))]; Vector2[] uvs = new Vector2[vertices.Length]; int shapeClosure = 1; int[] triangles = new int[((points - 1) * _subdivisions) * (6 * (sectionVertexCount - shapeClosure))]; for (int p = 0, s = 0, t = 0; p < points - 1; p++) { for (int i = p > 0 ? 1 : 0; i <= _subdivisions; i++) { //Calculates vertices float curveT = (float)i / (float)_subdivisions; Vector3 bezierPos = path.GetBezierPosition(p, curveT); //Gets the positionon the bezier curve at t Vector3 derivative = path.GetDerivativeDirection(p, curveT).normalized; //Gets the derivative on the bézier curve at t float blendT = path[p].blend.Evaluate(curveT); float angle = Mathf.Lerp(path[p].normalAngle, path[p + 1].normalAngle, blendT); //Gets the normal angle Vector3 normal = Quaternion.AngleAxis(angle, Vector3.back) * path[p].normal; //Calculates the normal normal = Quaternion.LookRotation(derivative) * normal; //Applys derivative rotation to the normal Quaternion secRotation = Quaternion.LookRotation(derivative, normal); Vector2 pointScale = Vector2.Lerp(path[p].scale, path[p + 1].scale, blendT); pointScale = new Vector2(pointScale.x * _scale.x, pointScale.y * _scale.y); //Debug.DrawRay(transform.position + path.GetBezierPosition(p, curveT), normal, Color.yellow); float uvRes = ((float)s * _uvResolution) / _subdivisions; //Vertices and Uvs for (int vert = 0; vert < sectionVertexCount; vert++) { Vector2 pointPos = (Vector3)section.GetVerticePosition(vert); pointPos.x *= pointScale.x; pointPos.y *= pointScale.y; vertices[s * sectionVertexCount + vert] = bezierPos + secRotation * (pointPos); uvs[s * sectionVertexCount + vert] = new Vector2(vert, uvRes); } //Draws triangle if (s > 0) { int subdivIndex = (s - 1) * (sectionVertexCount); for (int vert = 0; vert < sectionVertexCount - shapeClosure; vert++) { for (int tri = 0; tri < TRIS_DRAW_ORDER.Length; tri++) { int targetVert = TRIS_DRAW_ORDER[tri]; if (targetVert >= 2) { targetVert += sectionVertexCount - 2; } if (vert != sectionVertexCount - 1 || (TRIS_DRAW_ORDER[tri] == 0 || TRIS_DRAW_ORDER[tri] == 2)) { targetVert = subdivIndex + targetVert + vert; } else if (vert == sectionVertexCount - 1 && (TRIS_DRAW_ORDER[tri] == 1 || TRIS_DRAW_ORDER[tri] == 3)) { targetVert = subdivIndex + targetVert - 1; } //if(vert == sectionVertexCount - 1) Debug.Log("Loop vertice to : " + (subdivIndex + targetVert) + " at order " + tri); triangles[t] = targetVert; t++; } } } s++; } } Mesh finalMesh = new Mesh(); finalMesh.name = "Generated_Path_" + gameObject.GetInstanceID(); finalMesh.vertices = vertices; finalMesh.uv = uvs; finalMesh.triangles = triangles; finalMesh.RecalculateNormals(); finalMesh.RecalculateBounds(); return(finalMesh); }