diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.XML b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.XML index 24a52cf..7046bfe 100644 --- a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.XML +++ b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.XML @@ -996,6 +996,9 @@ Curved path (which uses Catmull-Rom curves) + + EXPERIMENTAL: Curved path (which uses Cubic Bezier curves, where each point requires two extra control points) + Path control point diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll index c4b2d84..a5fcb96 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll and b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll.mdb b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll.mdb index 8324f2d..335fc88 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll.mdb and b/UnityTests.Unity5/Assets/Demigiant/DOTween/DOTween.dll.mdb differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll index 530f732..6d6ef1f 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll and b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb index ac244b4..9fa0546 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb and b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll index a43718e..a0c8de8 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll and b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll.mdb b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll.mdb index e0c1b18..d8663d5 100644 Binary files a/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll.mdb and b/UnityTests.Unity5/Assets/Demigiant/DOTween/Editor/DOTweenUpgradeManager.dll.mdb differ diff --git a/UnityTests.Unity5/Assets/Demigiant/DemiLib/Core/Editor/Imgs/whiteSquare.png.meta b/UnityTests.Unity5/Assets/Demigiant/DemiLib/Core/Editor/Imgs/whiteSquare.png.meta index 7d4a322..64c38ed 100644 --- a/UnityTests.Unity5/Assets/Demigiant/DemiLib/Core/Editor/Imgs/whiteSquare.png.meta +++ b/UnityTests.Unity5/Assets/Demigiant/DemiLib/Core/Editor/Imgs/whiteSquare.png.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 guid: d3e15b806a8368742ba6f10e794d7b76 -timeCreated: 1551216472 +timeCreated: 1551364502 licenseType: Pro TextureImporter: fileIDToRecycleName: {} diff --git a/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs b/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs new file mode 100644 index 0000000..109070d --- /dev/null +++ b/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs @@ -0,0 +1,67 @@ +using System.Collections; +using System.Collections.Generic; +using DG.Tweening; +using UnityEngine; + +public class PathsBezier : BrainBase +{ + public Transform target; + public float duration = 3; + public bool closedPath = false; + public Ease easeType = Ease.Linear; + public bool loop = true; + public LoopType loopType = LoopType.Restart; + public int wpsToUse = 0; + public Vector3[] wps0 = new[] { + new Vector3(1, 1, 0), // wp + new Vector3(0, 0.75f, 0), + new Vector3(0.25f, 1, 0), + new Vector3(2, 0, 0), // wp + new Vector3(1.75f, 1, 0), + new Vector3(2, 0.75f, 0), + new Vector3(1, -1, 0), // wp + new Vector3(2, -0.75f, 0), + new Vector3(1.75f, -1, 0), + }; + public Vector3[] wps1 = new[] { + new Vector3(1, 1, 0), // wp + new Vector3(0, 0.75f, 0), + new Vector3(0.25f, 1, 0), + new Vector3(2, 0, 0), // wp + new Vector3(1.75f, 1, 0), + new Vector3(2, 0.75f, 0), + new Vector3(1, -1, 0), // wp + new Vector3(2, -0.75f, 0), + new Vector3(1.75f, -1, 0), + new Vector3(0, 0, 0), // wp + new Vector3(0.25f, -1, 0), + new Vector3(0f, -0.75f, 0) + }; + public Vector3[] wps2 = new[] { + new Vector3(0, 0, 0), // wp + new Vector3(0, 0.75f, 0), + new Vector3(0.25f, 1, 0), + new Vector3(1, 1, 0), // wp + new Vector3(0, 0.75f, 0), + new Vector3(0.25f, 1, 0), + new Vector3(2, 0, 0), // wp + new Vector3(1.75f, 1, 0), + new Vector3(2, 0.75f, 0), + new Vector3(1, -1, 0), // wp + new Vector3(2, -0.75f, 0), + new Vector3(1.75f, -1, 0), + new Vector3(0, 0, 0), // wp + new Vector3(0.25f, -1, 0), + new Vector3(0f, -0.75f, 0) + }; + + IEnumerator Start() + { + yield return new WaitForSeconds(0.5f); + + Debug.Log("Creating CubicBezier path"); + Vector3[] wps = wpsToUse == 0 ? wps0 : wpsToUse == 1 ? wps1 : wps2; + target.DOPath(wps, duration, PathType.CubicBezier).SetOptions(closedPath).SetLookAt(0.001f) + .SetLoops(loop ? -1 : 1, loopType).SetEase(easeType); + } +} \ No newline at end of file diff --git a/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs.meta b/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs.meta new file mode 100644 index 0000000..e3c1dea --- /dev/null +++ b/UnityTests.Unity5/Assets/_Tests/PathsBezier.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4b14f70d99c4aea40be7cc18724a9246 +timeCreated: 1551356786 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity b/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity new file mode 100644 index 0000000..e0cfec9 Binary files /dev/null and b/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity differ diff --git a/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity.meta b/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity.meta new file mode 100644 index 0000000..7e45929 --- /dev/null +++ b/UnityTests.Unity5/Assets/_Tests/PathsBezier.unity.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 474761fd35fdb8a44b5b72b55c6c4aa7 +DefaultImporter: + userData: diff --git a/_DOTween.Assembly/DOTween/DOTween.cs b/_DOTween.Assembly/DOTween/DOTween.cs index 36c8729..02504b9 100644 --- a/_DOTween.Assembly/DOTween/DOTween.cs +++ b/_DOTween.Assembly/DOTween/DOTween.cs @@ -32,7 +32,7 @@ namespace DG.Tweening public class DOTween { /// DOTween's version - public static readonly string Version = "1.2.201"; // Last version before modules: 1.1.755 + public static readonly string Version = "1.2.210"; // Last version before modules: 1.1.755 /////////////////////////////////////////////// // Options //////////////////////////////////// diff --git a/_DOTween.Assembly/DOTween/PathType.cs b/_DOTween.Assembly/DOTween/PathType.cs index e7c711c..1153196 100644 --- a/_DOTween.Assembly/DOTween/PathType.cs +++ b/_DOTween.Assembly/DOTween/PathType.cs @@ -15,7 +15,7 @@ namespace DG.Tweening Linear, /// Curved path (which uses Catmull-Rom curves) CatmullRom, -// /// Curved path (which uses Cubic Bezier curves, where each point requires two extra control points) -// CubicBezier // Under development + /// EXPERIMENTAL: Curved path (which uses Cubic Bezier curves, where each point requires two extra control points) + CubicBezier } } \ No newline at end of file diff --git a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/ControlPoint.cs b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/ControlPoint.cs index b9026f8..d241fc8 100644 --- a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/ControlPoint.cs +++ b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/ControlPoint.cs @@ -27,5 +27,10 @@ namespace DG.Tweening.Plugins.Core.PathCore { return new ControlPoint(cp.a + v, cp.b + v); } + + public override string ToString() + { + return "[" + a.ToString() + " | " + b.ToString() + "]"; + } } } \ No newline at end of file diff --git a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/CubicBezierDecoder.cs b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/CubicBezierDecoder.cs index 371f87e..eff37f5 100644 --- a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/CubicBezierDecoder.cs +++ b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/CubicBezierDecoder.cs @@ -4,35 +4,84 @@ // This work is subject to the terms at http://dotween.demigiant.com/license.php using System; +using System.Collections.Generic; using UnityEngine; namespace DG.Tweening.Plugins.Core.PathCore { internal class CubicBezierDecoder : ABSPathDecoder { - // wps must be in multiple of 3 (each waypoint has 2 control points), in this order: + // Used for temporary operations + static readonly ControlPoint[] _PartialControlPs = new ControlPoint[1]; + static readonly Vector3[] _PartialWps = new Vector3[2]; + + #region Methods + + // Finalize path and separate wps into stripped wps (no control points) and control points + // wps must be in multiple of 3 (each waypoint has 2 control points) plus one starting waypoint without control points, in this order: // - waypoint // - IN control point // - OUT control point + // NOTE: Control points have length of wps - 1 (first wp has no control point) internal override void FinalizePath(Path p, Vector3[] wps, bool isClosedPath) { + if (isClosedPath && !p.addedExtraEndWp) isClosedPath = false; + // Normally there's an extra wp without control points for the starting wp added by DOTween, + // but if isClosedPath consider an extra wp without control points at the end int wpsLen = wps.Length; - if (wpsLen < 6 || wpsLen % 3 != 0) { - Debug.LogError("CubicBezier paths must contain waypoints in multiple of 3 (1: waypoint, 2: IN control point, 3: OUT control point)"); + int diff = p.addedExtraStartWp ? 1 : 0; + if (p.addedExtraEndWp) diff++; + if (wpsLen < 3 + diff || (wpsLen - diff) % 3 != 0) { + // Report multiple of 3s error even if we're checking for multiple of 3 + starting point, + // because starting point is assigned by DOTween and not by user + Debug.LogError( + "CubicBezier paths must contain waypoints in multiple of 3 excluding the starting point added automatically by DOTween" + + " (1: waypoint, 2: IN control point, 3: OUT control point — the minimum amount of waypoints for a single curve is 3)" + ); return; } - int wpsOnlyLen = wpsLen / 3; - // Store control points - p.controlPoints = new ControlPoint[wpsOnlyLen]; +// // DEBUG +// for (int i = 0; i < wps.Length; ++i) { +// Debug.Log("WP " + i + " ► " + wps[i]); +// } +// Debug.Log("--------------------------------------"); +// // DEBUG END + + int wpsOnlyLen = diff + (wpsLen - diff) / 3; + // Store control points and stripped version of wps + Vector3[] strippedWps = new Vector3[wpsOnlyLen]; + p.controlPoints = new ControlPoint[wpsOnlyLen - 1]; // Exclude control points for first wp + strippedWps[0] = wps[0]; + int strippedWpIndex = 1; int cpIndex = 0; - for (int i = 0; i < wpsLen; i+=3) { - p.controlPoints[cpIndex] = new ControlPoint(wps[i+1], wps[i+2]); + for (int i = 3 + (p.addedExtraStartWp ? 0 : 2); i < wpsLen; i+=3) { + strippedWps[strippedWpIndex] = wps[i-2]; + strippedWpIndex++; + p.controlPoints[cpIndex] = new ControlPoint(wps[i-1], wps[i]); cpIndex++; } + p.wps = strippedWps; // Reassign stripped wps to path's wps +// // DEBUG +// for (int i = 0; i < strippedWps.Length; ++i) { +// Debug.Log("WP " + i + " ► " + strippedWps[i]); +// } +// for (int i = 0; i < p.controlPoints.Length; ++i) { +// Debug.Log("CP " + i + " ► " + p.controlPoints[i]); +// } +// // DEBUG END // Manage closed path if (isClosedPath) { - // TODO Bezier Closed Path + // Add control points for closed path + Vector3 wpEnd = p.wps[p.wps.Length - 2]; + Vector3 wpStart = p.wps[0]; + Vector3 cEnd = p.controlPoints[p.controlPoints.Length - 2].b; + Vector3 cStart = p.controlPoints[0].a; + float maxMagnitude = (wpStart - wpEnd).magnitude; + p.controlPoints[p.controlPoints.Length - 1] = new ControlPoint( + wpEnd + Vector3.ClampMagnitude(wpEnd - cEnd, maxMagnitude), + wpStart + Vector3.ClampMagnitude(wpStart - cStart, maxMagnitude) + ); } // Store total subdivisions p.subdivisions = wpsOnlyLen * p.subdivisionsXSegment; @@ -40,48 +89,36 @@ namespace DG.Tweening.Plugins.Core.PathCore SetTimeToLengthTables(p, p.subdivisions); // Store waypoints lengths SetWaypointsLengths(p, p.subdivisionsXSegment); - - -// // Add starting and ending control points (uses only one vector per control point) -// 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 * p.subdivisionsXSegment; -// // Store time to len tables -// SetTimeToLengthTables(p, p.subdivisions); -// // Store waypoints lengths -// SetWaypointsLengths(p, p.subdivisionsXSegment); } // controlPoints as a separate parameter so we can pass custom ones from SetWaypointsLengths + // Immense thanks to Vivek Tank's Gamasutra post about Bezier curves whose code I used for this: + // https://www.gamasutra.com/blogs/VivekTank/20180806/323709/How_to_work_with_Bezier_Curve_in_Games_with_Unity.php internal override Vector3 GetPoint(float perc, Vector3[] wps, Path p, ControlPoint[] controlPoints) { - int numSections = wps.Length - 1; // Considering also control points + int numSections = wps.Length - 1; int tSec = (int)Math.Floor(perc * numSections); int currPt = numSections - 1; if (currPt > tSec) currPt = tSec; - float u = perc * numSections - currPt; + float t = 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]; + Vector3 p0 = wps[currPt]; + Vector3 p1 = controlPoints[currPt].a; + Vector3 p2 = controlPoints[currPt].b; + Vector3 p3 = wps[currPt + 1]; - 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 - ); + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + Vector3 result = uuu * p0 + + 3 * uu * t * p1 + + 3 * u * tt * p2 + + ttt * p3; + + return result; } internal void SetTimeToLengthTables(Path p, int subdivisions) @@ -113,21 +150,20 @@ namespace DG.Tweening.Plugins.Core.PathCore 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]; +// _PartialControlPs[0].a = i == 1 ? p.controlPoints[0].a : p.wps[i - 2]; + _PartialControlPs[0] = p.controlPoints[i - 1]; + _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); + 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); + Vector3 currP = GetPoint(perc, _PartialWps, p, _PartialControlPs); partialLen += Vector3.Distance(currP, prevP); prevP = currP; } @@ -137,5 +173,7 @@ namespace DG.Tweening.Plugins.Core.PathCore // Assign p.wpLengths = wpLengths; } + + #endregion } } \ No newline at end of file diff --git a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/Path.cs b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/Path.cs index 3e9783e..1d9c7a4 100644 --- a/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/Path.cs +++ b/_DOTween.Assembly/DOTween/Plugins/Core/PathCore/Path.cs @@ -19,12 +19,13 @@ namespace DG.Tweening.Plugins.Core.PathCore // Static decoders stored to avoid creating new ones each time static CatmullRomDecoder _catmullRomDecoder; static LinearDecoder _linearDecoder; + static CubicBezierDecoder _cubicBezierDecoder; public float[] wpLengths; // Unit length of each waypoint (public so it can be accessed at runtime by external scripts) [SerializeField] internal PathType type; [SerializeField] internal int subdivisionsXSegment; // Subdivisions x each segment [SerializeField] internal int subdivisions; // Stored by PathPlugin > total subdivisions for whole path (derived automatically from subdivisionsXSegment) - [SerializeField] internal Vector3[] wps; // Waypoints (modified by PathPlugin when setting relative end value and change value) - also modified by DOTweenPathInspector + [SerializeField] internal Vector3[] wps; // Waypoints (modified by PathPlugin when setting relative end/change value or by CubicBezierDecoder) - also modified by DOTweenPathInspector [SerializeField] internal ControlPoint[] controlPoints; // Control points used by non-linear paths [SerializeField] internal float length; // Unit length of the path [SerializeField] internal bool isFinalized; // TRUE when the path has been finalized (either by starting the tween or if the path was created by the Path Editor) @@ -32,6 +33,7 @@ namespace DG.Tweening.Plugins.Core.PathCore [SerializeField] internal float[] timesTable; // Connected to lengthsTable, used for constant speed calculations [SerializeField] internal float[] lengthsTable; // Connected to timesTable, used for constant speed calculations internal int linearWPIndex = -1; // Waypoint towards which we're moving (only stored for linear paths, when calling GetPoint) + internal bool addedExtraStartWp, addedExtraEndWp; Path _incrementalClone; // Last incremental clone. Stored in case of incremental loops, to avoid recreating a new path every time int _incrementalIndex = 0; @@ -268,6 +270,10 @@ namespace DG.Tweening.Plugins.Core.PathCore if (_linearDecoder == null) _linearDecoder = new LinearDecoder(); _decoder = _linearDecoder; break; + case PathType.CubicBezier: + if (_cubicBezierDecoder == null) _cubicBezierDecoder = new CubicBezierDecoder(); + _decoder = _cubicBezierDecoder; + break; default: // Catmull-Rom if (_catmullRomDecoder == null) _catmullRomDecoder = new CatmullRomDecoder(); _decoder = _catmullRomDecoder; diff --git a/_DOTween.Assembly/DOTween/Plugins/Options/PathOptions.cs b/_DOTween.Assembly/DOTween/Plugins/Options/PathOptions.cs index 76b6911..73eba78 100644 --- a/_DOTween.Assembly/DOTween/Plugins/Options/PathOptions.cs +++ b/_DOTween.Assembly/DOTween/Plugins/Options/PathOptions.cs @@ -34,6 +34,7 @@ namespace DG.Tweening.Plugins.Options internal Quaternion startupRot; // Used to reset orientation when rewinding internal float startupZRot; // Used to store Z value in case of lock Z, in order to rotate things differently + internal bool addedExtraStartWp, addedExtraEndWp; public void Reset() { diff --git a/_DOTween.Assembly/DOTween/Plugins/PathPlugin.cs b/_DOTween.Assembly/DOTween/Plugins/PathPlugin.cs index 87397a5..2dc6fb4 100644 --- a/_DOTween.Assembly/DOTween/Plugins/PathPlugin.cs +++ b/_DOTween.Assembly/DOTween/Plugins/PathPlugin.cs @@ -68,15 +68,25 @@ namespace DG.Tweening.Plugins int additionalWps = 0; bool hasAdditionalStartingP = false, hasAdditionalEndingP = false; - // Create final wps and add eventual starting/ending waypoints -// if (path.wps[0] != currVal) { + // Create final wps and add eventual starting/ending waypoints. if (!Utils.Vector3AreApproximatelyEqual(path.wps[0], currVal)) { hasAdditionalStartingP = true; additionalWps += 1; } - if (t.plugOptions.isClosedPath && path.wps[unmodifiedWpsLen - 1] != currVal) { - hasAdditionalEndingP = true; - additionalWps += 1; + if (t.plugOptions.isClosedPath) { + Vector3 endWp = path.wps[unmodifiedWpsLen - 1]; + if (path.type == PathType.CubicBezier) { + if (unmodifiedWpsLen < 3) { + Debug.LogError( + "CubicBezier paths must contain waypoints in multiple of 3 excluding the starting point added automatically by DOTween" + + " (1: waypoint, 2: IN control point, 3: OUT control point — the minimum amount of waypoints for a single curve is 3)" + ); + } else endWp = path.wps[unmodifiedWpsLen - 3]; + } + if (endWp != currVal) { + hasAdditionalEndingP = true; + additionalWps += 1; + } } int wpsLen = unmodifiedWpsLen + additionalWps; Vector3[] wps = new Vector3[wpsLen]; @@ -87,6 +97,8 @@ namespace DG.Tweening.Plugins path.wps = wps; // Finalize path + path.addedExtraStartWp = hasAdditionalStartingP; + path.addedExtraEndWp = hasAdditionalEndingP; path.FinalizePath(t.plugOptions.isClosedPath, t.plugOptions.lockPositionAxis, currVal); t.plugOptions.startupRot = trans.rotation; diff --git a/_DOTween.Assembly/bin/DOTween.XML b/_DOTween.Assembly/bin/DOTween.XML index 24a52cf..7046bfe 100644 --- a/_DOTween.Assembly/bin/DOTween.XML +++ b/_DOTween.Assembly/bin/DOTween.XML @@ -996,6 +996,9 @@ Curved path (which uses Catmull-Rom curves) + + EXPERIMENTAL: Curved path (which uses Cubic Bezier curves, where each point requires two extra control points) + Path control point diff --git a/_DOTween.Assembly/bin/DOTween.dll b/_DOTween.Assembly/bin/DOTween.dll index c4b2d84..a5fcb96 100644 Binary files a/_DOTween.Assembly/bin/DOTween.dll and b/_DOTween.Assembly/bin/DOTween.dll differ diff --git a/_DOTween.Assembly/bin/DOTween.dll.mdb b/_DOTween.Assembly/bin/DOTween.dll.mdb index 8324f2d..335fc88 100644 Binary files a/_DOTween.Assembly/bin/DOTween.dll.mdb and b/_DOTween.Assembly/bin/DOTween.dll.mdb differ diff --git a/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll b/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll index 530f732..6d6ef1f 100644 Binary files a/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll and b/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll differ diff --git a/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll.mdb b/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll.mdb index ac244b4..9fa0546 100644 Binary files a/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll.mdb and b/_DOTween.Assembly/bin/Editor/DOTweenEditor.dll.mdb differ diff --git a/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll b/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll index a43718e..a0c8de8 100644 Binary files a/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll and b/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll differ diff --git a/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll.mdb b/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll.mdb index e0c1b18..d8663d5 100644 Binary files a/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll.mdb and b/_DOTween.Assembly/bin/Editor/DOTweenUpgradeManager.dll.mdb differ