private void UpdateLine() { if (path != null && line != null) { int numPoints = Mathf.CeilToInt(path.GetLength() * pointsPerUnit); Vector3[] points = new Vector3[numPoints]; for (int i = 0; i < numPoints; i++) { points[i] = path.GetPoint(i / (float)(numPoints - 1)); } line.positionCount = numPoints; line.SetPositions(points); } }
public void BuildMesh() { if (path == null) { path = GetComponent <PathBase>(); } mf = GetComponent <MeshFilter>(); if (mf && path) { if (mf.sharedMesh != null) { DestroyImmediate(mf.sharedMesh); } if (mesh == null) { mesh = new Mesh(); } else { mesh.Clear(); } if (markDynamic) { mesh.MarkDynamic(); } verts.Clear(); indices.Clear(); normals.Clear(); uvs.Clear(); colors.Clear(); Vector3 lastPos = path.GetPoint(0f); Vector3 normal = -path.GetDirection(0f); verts.Add(transform.InverseTransformPoint(lastPos + normal * path.Radius / 2f)); normals.Add(transform.InverseTransformVector(normal)); uvs.Add(new Vector2(0f, 0f)); if (colorVerts) { colors.Add(colorGradient.Evaluate(0f)); } pathLength = path.GetLength() * fillAmount; dists.Clear(); iters.Clear(); iters.Add(0f); dists.Add(0f); float totalDist = 0f; float iter = 0f; while (iter < fillAmount) { float moveDist = spacing; while (moveDist > 0f && iter < fillAmount) { float prevIter = iter; iter += alphaIter; iter = Mathf.Clamp(iter, 0f, fillAmount); Vector3 pos = path.GetPoint(iter); Vector3 toPos = pos - lastPos; float toPosDist = toPos.magnitude; if (toPosDist < moveDist) { moveDist -= toPosDist; totalDist += toPosDist; lastPos = pos; } else { float alpha = moveDist / toPosDist; iter = Mathf.Lerp(prevIter, iter, alpha); lastPos = Vector3.Lerp(lastPos, pos, alpha); iters.Add(iter); totalDist += moveDist; dists.Add(totalDist); moveDist = 0f; } } } iters.Add(fillAmount); dists.Add(totalDist); LinePath linePath = path as LinePath; if (linePath) { // THIS IS A BAD ATTEMPT AT MAKING LINEPATHS WORK. NOT OFFICIALLY SUPPORTED int numPoints = linePath.Loop ? linePath.Points.Length : (linePath.Points.Length - 1); float alphaPerPoint = fillAmount / (float)numPoints; pointDirs.Clear(); pointIters.Clear(); for (int i = 1; i < numPoints; i++) { float alpha = alphaPerPoint * i; Vector3 preDir = linePath.GetDirection(alpha - SplineUtils.DefaultTraverseAlphaSpeed); Vector3 postDir = linePath.GetDirection(alpha + SplineUtils.DefaultTraverseAlphaSpeed); Vector3 dir = (preDir + postDir) / 2f; pointDirs.Add(dir); pointIters.Add(alpha); for (int j = 0; j < iters.Count; j++) { if (iters[j] > alpha) { iters.Insert(j, alpha); dists.Insert(j, alpha); // Cursed break; } } } for (int i = 0; i < iters.Count; i++) { Vector3 direction = path.GetDirection(iters[i]); float nearestDist = Mathf.Infinity; Vector3 nearestDir = direction; for (int j = 0; j < pointIters.Count; j++) { float iterDist = Mathf.Abs(pointIters[j] - iters[i]); if (iterDist < nearestDist && iterDist < lineCornerFalloff) { float alpha = Mathf.InverseLerp(lineCornerFalloff, 0f, iterDist); nearestDir = Vector3.Lerp(direction, pointDirs[j], alpha); nearestDist = iterDist; } } AddEdgeLoop(iters[i], i, nearestDir); } } else { for (int i = 0; i < iters.Count; i++) { AddEdgeLoop(iters[i], i); } } normal = path.GetDirection(fillAmount); verts.Add(transform.InverseTransformPoint(lastPos + normal * path.Radius / 2f)); uvs.Add(new Vector2(1, pathLength)); normals.Add(transform.InverseTransformVector(normal)); if (colorVerts) { colors.Add(colorGradient.Evaluate(1f)); } mesh.SetVertices(verts); mesh.SetTriangles(indices, 0); mesh.SetNormals(normals); mesh.SetUVs(0, uvs); if (colorVerts) { mesh.SetColors(colors); } mf.sharedMesh = mesh; OnMeshChanged(this); } }
public void BuildCollision() { if (this == null) { path.OnPathChanged -= Path_OnPathChanged; } if (path != null) { Transform capsuleRoot = transform.Find("CapsuleRoot"); if (capsuleRoot != null) { if (Application.IsPlaying(this)) { Destroy(capsuleRoot.gameObject); } else { DestroyImmediate(capsuleRoot.gameObject); } } if (useCapsules) { MeshCollider mc = GetComponent <MeshCollider>(); if (mc != null) { if (Application.IsPlaying(this)) { Destroy(mc); } else { DestroyImmediate(mc); } } capsuleRoot = new GameObject("CapsuleRoot").transform; capsuleRoot.SetParent(transform); capsuleRoot.ResetLocals(); colliders.Clear(); int numCapsules = Mathf.CeilToInt(path.GetLength() * capsulesPerUnit); for (int i = 1; i <= numCapsules; i++) { float prevAlpha = (i - 1) / (float)numCapsules; float alpha = i / (float)numCapsules; Vector3 prevPos = path.GetPoint(prevAlpha); Vector3 pos = path.GetPoint(alpha); GameObject capsuleGo = new GameObject("CapsuleCollider", typeof(CapsuleCollider)); CapsuleCollider capsule = capsuleGo.GetComponent <CapsuleCollider>(); capsule.transform.SetParent(capsuleRoot); capsule.transform.position = (prevPos + pos) / 2f; Vector3 lookDir = pos - prevPos; if (lookDir != Vector3.zero) { capsule.transform.forward = lookDir.normalized; } capsule.direction = 2; // Z float prevThickness = thicknessCurve.Evaluate(prevAlpha); float thickness = thicknessCurve.Evaluate(alpha); capsule.radius = path.Radius * (prevThickness + thickness) / 2f; capsule.height = (pos - prevPos).magnitude + capsule.radius; capsule.isTrigger = false; capsule.gameObject.layer = colliderLayer.layer; colliders.Add(capsule); } RefreshActiveColliders(); } else { MeshFilter mf = GetComponent <MeshFilter>(); if (mf == null) { mf = path.GetComponent <MeshFilter>(); } if (mf != null) { MeshCollider mc = mf.gameObject.GetComponent <MeshCollider>(); if (mc == null) { mc = mf.gameObject.AddComponent <MeshCollider>(); } mc.sharedMesh = mf.sharedMesh; } } #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif OnCollisionChanged(this); } }