/// <summary> /// Adds the correct starting and ending point so the path can be reached from the property's actual position. /// </summary> protected override void SetChangeVal() { if (orientType != OrientType.None) { // Store orient transform. if (orientTrans == null) { orientTrans = tweenObj.target as Transform; orZ = orientTrans.eulerAngles.z; } } // Create path. Vector3[] pts; int indMod = 1; int pAdd = (isClosedPath ? 1 : 0); int pointsLength = points.Length; if (isRelative) { hasAdditionalStartingP = false; Vector3 diff = points[0] - typedStartVal; // Path length is the same (plus control points). pts = new Vector3[pointsLength + 2 + pAdd]; for (int i = 0; i < pointsLength; ++i) pts[i + indMod] = points[i] - diff; } else { Vector3 currVal = (Vector3)GetValue(); // Calculate if currVal and start point are equal, // managing floating point imprecision. Vector3 diff = currVal - points[0]; if (diff.x < 0) diff.x = -diff.x; if (diff.y < 0) diff.y = -diff.y; if (diff.z < 0) diff.z = -diff.z; if (diff.x < EPSILON && diff.y < EPSILON && diff.z < EPSILON) { // Path length is the same (plus control points). hasAdditionalStartingP = false; pts = new Vector3[pointsLength + 2 + pAdd]; } else { // Path needs additional point for current value as starting point (plus control points). hasAdditionalStartingP = true; pts = new Vector3[pointsLength + 3 + pAdd]; if (tweenObj.isFrom) { pts[pts.Length - 2] = currVal; } else { pts[1] = currVal; indMod = 2; } } for (int i = 0; i < pointsLength; ++i) { pts[i + indMod] = points[i]; } } pointsLength = pts.Length; if (isClosedPath) { // Close path. pts[pointsLength - 2] = pts[1]; } // Add control points. if (isClosedPath) { pts[0] = pts[pointsLength - 3]; pts[pointsLength - 1] = pts[2]; } else { pts[0] = pts[1]; Vector3 lastP = pts[pointsLength - 2]; Vector3 diffV = lastP - pts[pointsLength - 3]; pts[pointsLength - 1] = lastP + diffV; } // Manage eventual lockPositionAxis. if (lockPositionAxis != Axis.None) { bool lockX = ((lockPositionAxis & Axis.X) == Axis.X); bool lockY = ((lockPositionAxis & Axis.Y) == Axis.Y); bool lockZ = ((lockPositionAxis & Axis.Z) == Axis.Z); Vector3 orPos = typedStartVal; for (int i = 0; i < pointsLength; ++i) { Vector3 pt = pts[i]; pts[i] = new Vector3( lockX ? orPos.x : pt.x, lockY ? orPos.y : pt.y, lockZ ? orPos.z : pt.z ); } } // Create the path. path = new Path(pathType, pts); // Store arc lengths tables for constant speed. path.StoreTimeToLenTables(path.path.Length * SUBDIVISIONS_MULTIPLIER); if (!isClosedPath) { // Store the changeVal used for Incremental loops diffChangeVal = pts[pointsLength - 2] - pts[1]; } }
/// <summary> /// Returns the point at the given percentage (0 to 1), /// considering the path at constant speed. /// Used by DoUpdate and by Tweener.GetPointOnPath. /// </summary> /// <param name="t"> /// The percentage (0 to 1) at which to get the point. /// </param> /// <param name="p_updatePathPerc"> /// IF <c>true</c> updates also <see cref="pathPerc"/> value /// (necessary if this method is called for an update). /// </param> /// <param name="p_path"> /// IF not NULL uses the given path instead than the default one. /// </param> /// <param name="out_waypointIndex"> /// Index of waypoint we're moving to (or where we are). Only used for Linear paths. /// </param> internal Vector3 GetConstPointOnPath(float t, bool p_updatePathPerc, Path p_path, out int out_waypointIndex) { if (p_updatePathPerc) return p_path.GetConstPoint(t, out pathPerc, out out_waypointIndex); out_waypointIndex = -1; return path.GetConstPoint(t); }
// If path is lineas, waypointsLengths were stored when calling StoreTimeToLenTables internal void StoreWaypointsLengths(int p_subdivisions) { // Create a relative path between each waypoint, // with its start and end control lines coinciding with the next/prev waypoints. int len = path.Length - 2; waypointsLength = new float[len]; waypointsLength[0] = 0; Path partialPath = null; for (int i = 2; i < len + 1; ++i) { // Create partial path Vector3[] pts = new Vector3[4]; pts[0] = path[i - 2]; pts[1] = path[i - 1]; pts[2] = path[i]; pts[3] = path[i + 1]; if (i == 2) { partialPath = new Path(pathType, pts); } else { partialPath.path = pts; } // Calculate length of partial path float partialLen = 0; float incr = 1f / p_subdivisions; Vector3 prevP = partialPath.GetPoint(0); for (int c = 1; c < p_subdivisions + 1; ++c) { float perc = incr * c; Vector3 currP = partialPath.GetPoint(perc); partialLen += Vector3.Distance(currP, prevP); prevP = currP; } waypointsLength[i - 1] = partialLen; } }