void OnDrawGizmos() { if (wrapper == null) { return; } if (!playing) { return; } float t = (Application.isPlaying ? Time.time : Time.realtimeSinceStartup) + movementSync; SplineLerpResult result = FollowLerp(t); Gizmos.color = Color.green; Gizmos.matrix = Matrix4x4.TRS(result.worldPosition, Quaternion.Euler(result.worldRotation), Vector3.one * FollowScale(t)); Gizmos.DrawWireCube(Vector3.zero, Vector3.one * 0.5f); Gizmos.matrix = Matrix4x4.identity; }
void FixedUpdate() { if (wrapper == null) { return; } if (!playing) { return; } t += Time.deltaTime; float scale = (Application.isPlaying ? FollowScale(t) : 1); result = FollowLerp(t); currenSection = result.section; currentSegment = result.segment; transform.position = result.worldPosition; transform.rotation = Quaternion.Euler(result.worldRotation); transform.localScale = Vector3.one * scale; }
// ======================================================================================================================== GETTERS // This is the crucial function for splines: the one which lets outside objects query for interpolated data. // To do so, they pass in a root transform to use as the owner of the spline, as well as a SplineLerpQuery, // which contains the desired parametrized time [0-1] on the spline and some additional interpolation settings. // This function then returns a SplineLerpResult which contains all of the interpolated information. internal SplineLerpResult Lerp(Transform root, SplineLerpQuery query) { // Failsafe - if this spline is degenerate, just return the first point and don't do any other interpolation if (totalLength == 0) { SplineLerpResult degenerateResult = new SplineLerpResult(); degenerateResult.worldPosition = Matrix4x4.TRS(root.position, root.rotation, root.lossyScale).MultiplyPoint3x4(vertices[0, 0]); return(degenerateResult); } // First, we need to find the section on the spline that contains the parametrized time being queried for. // Convert the parametrized time given into a time-position within the total length of the spline float p = Mathf.Clamp01(query.t) * totalLength; // If the query says to smooth along the entire spline, do that now if (query.movementSmoothing == SplineMovementSmoothing.WholeSpline) { p = Mathf.SmoothStep(0, totalLength, p / totalLength); } // Now, find the section of the spline that corresponds to that time-position, by using the total lengths // of each section. In doing so, make the time-position p local to that section int section; for (section = 0; section < sectionCount - 1; section++) { if (p > lengths[section, segmentCount - 1]) { p -= lengths[section, segmentCount - 1]; } else { break; } } // Now that p is located within a section (between two SplineNodes), we need to do more parameter calculation. // v is the [0-1] parameter which will lerp the non-positional values between the nodes, with optional value smoothing if the query says to // p is also updated so that it is smoothed between the nodes if the query says to float v = p / lengths[section, segmentCount - 1]; if (query.movementSmoothing == SplineMovementSmoothing.BetweenNodes) { p = Mathf.SmoothStep(0, lengths[section, segmentCount - 1], v); } if (query.valueSmoothing) { v = Mathf.SmoothStep(0, 1, v); } // Finally, find the segment within the found section that corresponds to p, by using the // cumulative segment lengths. In doing so, make p local to that segment int segment; for (segment = 0; segment < segmentCount - 1; segment++) { float l1 = lengths[section, segment]; float l2 = lengths[section, segment + 1]; float r = (p - l1) / (l2 - l1); if (r >= 0 && r <= 1 || segment == segmentCount - 2) { p = r; break; } } // Now that we finally know where we are in terms of sections and segments, we can do the interpolation. SplineLerpResult result = new SplineLerpResult(); // Position Vector3 localPos = Vector3.Lerp(vertices[section, segment], vertices[section, segment + 1], p); Matrix4x4 m = Matrix4x4.TRS(root.position, root.rotation, root.lossyScale); result.worldPosition = m.MultiplyPoint3x4(localPos); // Values SplineNode s = nodes[section]; SplineNode e = nodes[section + 1]; result.worldRotation = Vector3.Lerp(s.worldOrientation, e.worldOrientation, v); result.fieldOfView = Mathf.Lerp(s.fieldOfView, e.fieldOfView, v); result.tangent = (Tangent(vertices, section, segment, segmentCount, 0) + Tangent(vertices, section, segment, segmentCount, 1)) / 2; result.section = section; result.segment = segment; return(result); }