internal override Vector3 GetPoint(float perc, Vector3[] wps, Path p, ControlPoint[] controlPoints) { if (perc <= 0) { p.linearWPIndex = 1; return wps[0]; } int startPIndex = 0; int endPIndex = 0; int count = p.timesTable.Length; for (int i = 1; i < count; i++) { if (p.timesTable[i] >= perc) { startPIndex = i - 1; endPIndex = i; break; } } float startPPerc = p.timesTable[startPIndex]; float partialPerc = perc - startPPerc; float partialLen = p.length * partialPerc; Vector3 wp0 = wps[startPIndex]; Vector3 wp1 = wps[endPIndex]; p.linearWPIndex = endPIndex; return wp0 + Vector3.ClampMagnitude(wp1 - wp0, partialLen); }
// Linear exception: also sets waypoints lengths and doesn't set lengthsTable since it's useless internal void SetTimeToLengthTables(Path p, int subdivisions) { float pathLen = 0; int wpsLen = p.wps.Length; float[] wpLengths = new float[wpsLen]; Vector3 prevP = p.wps[0]; for (int i = 0; i < wpsLen; i++) { Vector3 currP = p.wps[i]; float dist = Vector3.Distance(currP, prevP); pathLen += dist; prevP = currP; wpLengths[i] = dist; } float[] timesTable = new float[wpsLen]; float tmpLen = 0; for (int i = 1; i < wpsLen; i++) { tmpLen += wpLengths[i]; timesTable[i] = tmpLen / pathLen; } // Assign p.length = pathLen; p.wpLengths = wpLengths; p.timesTable = timesTable; }
public static TweenerCore <Vector3, Path, PathOptions> CreateDOTweenPathTween( MonoBehaviour target, bool tweenRigidbody, bool isLocal, Plugins.Core.PathCore.Path myPath, float duration, PathMode pathMode ) { TweenerCore <Vector3, Path, PathOptions> t; #if true // PHYSICS_MARKER Rigidbody rBody = tweenRigidbody ? target.GetComponent <Rigidbody>() : null; if (tweenRigidbody && rBody != null) { t = isLocal ? rBody.DOLocalPath(myPath, duration, pathMode) : rBody.DOPath(myPath, duration, pathMode); } else { t = isLocal ? target.transform.DOLocalPath(myPath, duration, pathMode) : target.transform.DOPath(myPath, duration, pathMode); } #else t = isLocal ? target.transform.DOLocalPath(path, duration, pathMode) : target.transform.DOPath(path, duration, pathMode); #endif return(t); }
internal void SetWaypointsLengths(Path p, int subdivisions) { // Create a relative path between each waypoint, // with its start and end control lines coinciding with the next/prev waypoints. int count = p.wps.Length; float[] wpLengths = new float[count]; wpLengths[0] = 0; ControlPoint[] partialControlPs = new ControlPoint[2]; Vector3[] partialWps = new Vector3[2]; for (int i = 1; i < count; ++i) { // Create partial path partialControlPs[0].a = i == 1 ? p.controlPoints[0].a : p.wps[i - 2]; partialWps[0] = p.wps[i - 1]; partialWps[1] = p.wps[i]; partialControlPs[1].a = i == count - 1 ? p.controlPoints[1].a : p.wps[i + 1]; // Calculate length of partial path float partialLen = 0; float incr = 1f / subdivisions; Vector3 prevP = GetPoint(0, partialWps, p, partialControlPs); for (int c = 1; c < subdivisions + 1; ++c) { float perc = incr * c; Vector3 currP = GetPoint(perc, partialWps, p, partialControlPs); partialLen += Vector3.Distance(currP, prevP); prevP = currP; } wpLengths[i] = partialLen; } // Assign p.wpLengths = wpLengths; }
internal override void FinalizePath(Path p, Vector3[] wps, bool isClosedPath) { p.controlPoints = null; // Store time to len tables p.subdivisions = (wps.Length) * p.subdivisionsXSegment; // Unused SetTimeToLengthTables(p, p.subdivisions); }
static public int get_wpLengths(IntPtr l) { try { DG.Tweening.Plugins.Core.PathCore.Path self = (DG.Tweening.Plugins.Core.PathCore.Path)checkSelf(l); pushValue(l, true); pushValue(l, self.wpLengths); return(2); } catch (Exception e) { return(error(l, e)); } }
static public int set_wpLengths(IntPtr l) { try { DG.Tweening.Plugins.Core.PathCore.Path self = (DG.Tweening.Plugins.Core.PathCore.Path)checkSelf(l); System.Single[] v; checkArray(l, 2, out v); self.wpLengths = v; pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static int QPYX_get_endValue_YXQP(IntPtr L_YXQP) { object QPYX_o_YXQP = null; try { QPYX_o_YXQP = ToLua.ToObject(L_YXQP, 1); DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions> QPYX_obj_YXQP = (DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions>)QPYX_o_YXQP; DG.Tweening.Plugins.Core.PathCore.Path QPYX_ret_YXQP = QPYX_obj_YXQP.endValue; ToLua.PushObject(L_YXQP, QPYX_ret_YXQP); return(1); } catch (Exception QPYX_e_YXQP) { return(LuaDLL.toluaL_exception(L_YXQP, QPYX_e_YXQP, QPYX_o_YXQP, "attempt to index endValue on a nil value")); } }
static int QPYX_set_changeValue_YXQP(IntPtr L_YXQP) { object QPYX_o_YXQP = null; try { QPYX_o_YXQP = ToLua.ToObject(L_YXQP, 1); DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions> QPYX_obj_YXQP = (DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions>)QPYX_o_YXQP; DG.Tweening.Plugins.Core.PathCore.Path QPYX_arg0_YXQP = (DG.Tweening.Plugins.Core.PathCore.Path)ToLua.CheckObject <DG.Tweening.Plugins.Core.PathCore.Path>(L_YXQP, 2); QPYX_obj_YXQP.changeValue = QPYX_arg0_YXQP; return(0); } catch (Exception QPYX_e_YXQP) { return(LuaDLL.toluaL_exception(L_YXQP, QPYX_e_YXQP, QPYX_o_YXQP, "attempt to index changeValue on a nil value")); } }
static int set_changeValue(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions> obj = (DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions>)o; DG.Tweening.Plugins.Core.PathCore.Path arg0 = (DG.Tweening.Plugins.Core.PathCore.Path)ToLua.CheckObject <DG.Tweening.Plugins.Core.PathCore.Path>(L, 2); obj.changeValue = arg0; return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e, o, "attempt to index changeValue on a nil value")); } }
static int set_path(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); DG.Tweening.DOTweenPath obj = (DG.Tweening.DOTweenPath)o; DG.Tweening.Plugins.Core.PathCore.Path arg0 = (DG.Tweening.Plugins.Core.PathCore.Path)ToLua.CheckObject(L, 2, typeof(DG.Tweening.Plugins.Core.PathCore.Path)); obj.path = arg0; return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index path on a nil value" : e.Message)); } }
static int get_path(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); DG.Tweening.DOTweenPath obj = (DG.Tweening.DOTweenPath)o; DG.Tweening.Plugins.Core.PathCore.Path ret = obj.path; ToLua.PushObject(L, ret); return(1); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index path on a nil value" : e.Message)); } }
static int get_changeValue(IntPtr L) { object o = null; try { o = ToLua.ToObject(L, 1); DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions> obj = (DG.Tweening.Core.TweenerCore <UnityEngine.Vector3, DG.Tweening.Plugins.Core.PathCore.Path, DG.Tweening.Plugins.Options.QuaternionOptions>)o; DG.Tweening.Plugins.Core.PathCore.Path ret = obj.changeValue; ToLua.PushObject(L, ret); return(1); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e, o, "attempt to index changeValue on a nil value")); } }
static public int constructor(IntPtr l) { try { DG.Tweening.Plugins.Core.PathCore.Path o; DG.Tweening.PathType a1; checkEnum(l,2,out a1); UnityEngine.Vector3[] a2; checkArray(l,3,out a2); System.Int32 a3; checkType(l,4,out a3); System.Nullable<UnityEngine.Color> a4; checkNullable(l,5,out a4); o=new DG.Tweening.Plugins.Core.PathCore.Path(a1,a2,a3,a4); pushValue(l,true); pushValue(l,o); return 2; } catch(Exception e) { return error(l,e); } }
// controlPoints as a separate parameter so we can pass custom ones from SetWaypointsLengths internal override Vector3 GetPoint(float perc, Vector3[] wps, Path p, ControlPoint[] controlPoints) { int numSections = wps.Length - 1; // Considering also control points int tSec = (int)Math.Floor(perc * numSections); int currPt = numSections - 1; if (currPt > tSec) currPt = tSec; float u = perc * numSections - currPt; Vector3 a = currPt == 0 ? controlPoints[0].a : wps[currPt - 1]; Vector3 b = wps[currPt]; Vector3 c = wps[currPt + 1]; Vector3 d = currPt + 2 > wps.Length - 1 ? controlPoints[1].a : wps[currPt + 2]; return .5f * ( (-a + 3f * b - 3f * c + d) * (u * u * u) + (2f * a - 5f * b + 4f * c - d) * (u * u) + (-a + c) * u + 2f * b ); }
internal void SetTimeToLengthTables(Path p, int subdivisions) { float pathLen = 0; float incr = 1f / subdivisions; float[] timesTable = new float[subdivisions]; float[] lengthsTable = new float[subdivisions]; Vector3 prevP = GetPoint(0, p.wps, p, p.controlPoints); for (int i = 1; i < subdivisions + 1; ++i) { float perc = incr * i; Vector3 currP = GetPoint(perc, p.wps, p, p.controlPoints); pathLen += Vector3.Distance(currP, prevP); prevP = currP; timesTable[i - 1] = perc; lengthsTable[i - 1] = pathLen; } // Assign p.length = pathLen; p.timesTable = timesTable; p.lengthsTable = lengthsTable; }
static public int constructor(IntPtr l) { try { DG.Tweening.Plugins.Core.PathCore.Path o; DG.Tweening.PathType a1; checkEnum(l, 2, out a1); UnityEngine.Vector3[] a2; checkArray(l, 3, out a2); System.Int32 a3; checkType(l, 4, out a3); System.Nullable <UnityEngine.Color> a4; checkNullable(l, 5, out a4); o = new DG.Tweening.Plugins.Core.PathCore.Path(a1, a2, a3, a4); pushValue(l, true); pushValue(l, o); return(2); } catch (Exception e) { return(error(l, e)); } }
internal override void FinalizePath(Path p, Vector3[] wps, bool isClosedPath) { // Add starting and ending control points (uses only one vector per control point) int wpsLen = wps.Length; if (p.controlPoints == null || p.controlPoints.Length != 2) p.controlPoints = new ControlPoint[2]; if (isClosedPath) { p.controlPoints[0] = new ControlPoint(wps[wpsLen - 2], Vector3.zero); p.controlPoints[1] = new ControlPoint(wps[1], Vector3.zero); } else { p.controlPoints[0] = new ControlPoint(wps[1], Vector3.zero); Vector3 lastP = wps[wpsLen - 1]; Vector3 diffV = lastP - wps[wpsLen - 2]; p.controlPoints[1] = new ControlPoint(lastP + diffV, Vector3.zero); } // Store total subdivisions // p.subdivisions = (wpsLen + 2) * p.subdivisionsXSegment; p.subdivisions = wpsLen * p.subdivisionsXSegment; // Store time to len tables SetTimeToLengthTables(p, p.subdivisions); // Store waypoints lengths SetWaypointsLengths(p, p.subdivisionsXSegment); }
internal static TweenerCore<Vector3, Path, PathOptions> DOLocalPath( this Transform target, Path path, float duration, PathMode pathMode = PathMode.Full3D ) { TweenerCore<Vector3, Path, PathOptions> t = DOTween.To(PathPlugin.Get(), () => target.localPosition, x => target.localPosition = x, path, duration) .SetTarget(target); t.plugOptions.mode = pathMode; return t; }
internal void SetWaypointsLengths(Path p, int subdivisions) { // Does nothing (waypoints lenghts were stored inside SetTimeToLengthTables) }
// Gets a point on the path at the given percentage (0 to 1) internal abstract Vector3 GetPoint(float perc, Vector3[] wps, Path p, ControlPoint[] controlPoints);
// Refreshes the waypoints used to draw non-linear gizmos and the PathInspector scene view. // Called by Draw method or by DOTweenPathInspector internal static void RefreshNonLinearDrawWps(Path p) { int wpsCount = p.wps.Length; int gizmosSubdivisions = wpsCount * 10; if (p.nonLinearDrawWps == null || p.nonLinearDrawWps.Length != gizmosSubdivisions + 1) p.nonLinearDrawWps = new Vector3[gizmosSubdivisions + 1]; for (int i = 0; i <= gizmosSubdivisions; ++i) { float perc = i / (float)gizmosSubdivisions; Vector3 wp = p.GetPoint(perc); p.nonLinearDrawWps[i] = wp; } }
// Clones this path with the given loop increment internal Path CloneIncremental(int loopIncrement) { if (_incrementalClone != null) { if (_incrementalIndex == loopIncrement) return _incrementalClone; _incrementalClone.Destroy(); } int wpsLen = wps.Length; Vector3 diff = wps[wpsLen - 1] - wps[0]; Vector3[] incrWps = new Vector3[wps.Length]; for (int i = 0; i < wpsLen; ++i) incrWps[i] = wps[i] + (diff * loopIncrement); int cpsLen = controlPoints.Length; ControlPoint[] incrCps = new ControlPoint[cpsLen]; for (int i = 0; i < cpsLen; ++i) incrCps[i] = controlPoints[i] + (diff * loopIncrement); Vector3[] incrNonLinearDrawWps = null; if (nonLinearDrawWps != null) { int nldLen = nonLinearDrawWps.Length; incrNonLinearDrawWps = new Vector3[nldLen]; for (int i = 0; i < nldLen; ++i) incrNonLinearDrawWps[i] = nonLinearDrawWps[i] + (diff * loopIncrement); } _incrementalClone = new Path(); _incrementalIndex = loopIncrement; _incrementalClone.type = type; _incrementalClone.subdivisionsXSegment = subdivisionsXSegment; _incrementalClone.subdivisions = subdivisions; _incrementalClone.wps = incrWps; _incrementalClone.controlPoints = incrCps; if (DOTween.isUnityEditor) DOTween.GizmosDelegates.Add(_incrementalClone.Draw); _incrementalClone.length = length; _incrementalClone.wpLengths = wpLengths; _incrementalClone.timesTable = timesTable; _incrementalClone.lengthsTable = lengthsTable; _incrementalClone._decoder = _decoder; _incrementalClone.nonLinearDrawWps = incrNonLinearDrawWps; _incrementalClone.targetPosition = targetPosition; _incrementalClone.lookAtPosition = lookAtPosition; _incrementalClone.isFinalized = true; return _incrementalClone; }
// USED EXTERNALLY, to output a series of points that can be used to draw the path outside of DOTween // (called by TweenExtensions.PathGetDrawPoints) internal static Vector3[] GetDrawPoints(Path p, int drawSubdivisionsXSegment) { int wpsCount = p.wps.Length; if (p.type == PathType.Linear) return p.wps; int gizmosSubdivisions = wpsCount * drawSubdivisionsXSegment; Vector3[] drawPoints = new Vector3[gizmosSubdivisions + 1]; for (int i = 0; i <= gizmosSubdivisions; ++i) { float perc = i / (float)gizmosSubdivisions; Vector3 wp = p.GetPoint(perc); drawPoints[i] = wp; } return drawPoints; }
static void Draw(Path p) { if (p.timesTable == null) return; Color gizmosFadedCol = p.gizmoColor; gizmosFadedCol.a *= 0.5f; Gizmos.color = p.gizmoColor; int wpsCount = p.wps.Length; if (p._changed || p.type != PathType.Linear && p.nonLinearDrawWps == null) { p._changed = false; if (p.type != PathType.Linear) { // Store draw points RefreshNonLinearDrawWps(p); } } // Draw path Vector3 currPt; Vector3 prevPt; switch (p.type) { case PathType.Linear: prevPt = p.wps[0]; for (int i = 0; i < wpsCount; ++i) { currPt = p.wps[i]; Gizmos.DrawLine(currPt, prevPt); prevPt = currPt; } break; default: // Curved prevPt = p.nonLinearDrawWps[0]; int count = p.nonLinearDrawWps.Length; for (int i = 1; i < count; ++i) { currPt = p.nonLinearDrawWps[i]; Gizmos.DrawLine(currPt, prevPt); prevPt = currPt; } break; } Gizmos.color = gizmosFadedCol; const float spheresSize = 0.075f; // Draw path control points for (int i = 0; i < wpsCount; ++i) Gizmos.DrawSphere(p.wps[i], spheresSize); // Draw eventual path lookAt if (p.lookAtPosition != null) { Vector3 lookAtP = (Vector3)p.lookAtPosition; Gizmos.DrawLine(p.targetPosition, lookAtP); Gizmos.DrawWireSphere(lookAtP, spheresSize); } }
// Finalizes the path, assigning eventual control points and storing all required data internal abstract void FinalizePath(Path p, Vector3[] wps, bool isClosedPath);