mirror of
https://github.com/Cardidi/dotween-upm-fork.git
synced 2025-12-20 09:16:02 +08:00
PathType.CubicBezier implemented with all DOTween's features (more tests coming)
This commit is contained in:
parent
4d55885166
commit
acacc85b29
@ -996,6 +996,9 @@
|
|||||||
<member name="F:DG.Tweening.PathType.CatmullRom">
|
<member name="F:DG.Tweening.PathType.CatmullRom">
|
||||||
<summary>Curved path (which uses Catmull-Rom curves)</summary>
|
<summary>Curved path (which uses Catmull-Rom curves)</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="F:DG.Tweening.PathType.CubicBezier">
|
||||||
|
<summary><code>EXPERIMENTAL: </code>Curved path (which uses Cubic Bezier curves, where each point requires two extra control points)</summary>
|
||||||
|
</member>
|
||||||
<member name="T:DG.Tweening.Plugins.Core.PathCore.ControlPoint">
|
<member name="T:DG.Tweening.Plugins.Core.PathCore.ControlPoint">
|
||||||
<summary>
|
<summary>
|
||||||
Path control point
|
Path control point
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: d3e15b806a8368742ba6f10e794d7b76
|
guid: d3e15b806a8368742ba6f10e794d7b76
|
||||||
timeCreated: 1551216472
|
timeCreated: 1551364502
|
||||||
licenseType: Pro
|
licenseType: Pro
|
||||||
TextureImporter:
|
TextureImporter:
|
||||||
fileIDToRecycleName: {}
|
fileIDToRecycleName: {}
|
||||||
|
|||||||
67
UnityTests.Unity5/Assets/_Tests/PathsBezier.cs
Normal file
67
UnityTests.Unity5/Assets/_Tests/PathsBezier.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
UnityTests.Unity5/Assets/_Tests/PathsBezier.cs.meta
Normal file
12
UnityTests.Unity5/Assets/_Tests/PathsBezier.cs.meta
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4b14f70d99c4aea40be7cc18724a9246
|
||||||
|
timeCreated: 1551356786
|
||||||
|
licenseType: Pro
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
UnityTests.Unity5/Assets/_Tests/PathsBezier.unity
Normal file
BIN
UnityTests.Unity5/Assets/_Tests/PathsBezier.unity
Normal file
Binary file not shown.
4
UnityTests.Unity5/Assets/_Tests/PathsBezier.unity.meta
Normal file
4
UnityTests.Unity5/Assets/_Tests/PathsBezier.unity.meta
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 474761fd35fdb8a44b5b72b55c6c4aa7
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
||||||
@ -32,7 +32,7 @@ namespace DG.Tweening
|
|||||||
public class DOTween
|
public class DOTween
|
||||||
{
|
{
|
||||||
/// <summary>DOTween's version</summary>
|
/// <summary>DOTween's version</summary>
|
||||||
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 ////////////////////////////////////
|
// Options ////////////////////////////////////
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace DG.Tweening
|
|||||||
Linear,
|
Linear,
|
||||||
/// <summary>Curved path (which uses Catmull-Rom curves)</summary>
|
/// <summary>Curved path (which uses Catmull-Rom curves)</summary>
|
||||||
CatmullRom,
|
CatmullRom,
|
||||||
// /// <summary>Curved path (which uses Cubic Bezier curves, where each point requires two extra control points)</summary>
|
/// <summary><code>EXPERIMENTAL: </code>Curved path (which uses Cubic Bezier curves, where each point requires two extra control points)</summary>
|
||||||
// CubicBezier // Under development
|
CubicBezier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,5 +27,10 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
{
|
{
|
||||||
return new ControlPoint(cp.a + v, cp.b + v);
|
return new ControlPoint(cp.a + v, cp.b + v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "[" + a.ToString() + " | " + b.ToString() + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,35 +4,84 @@
|
|||||||
// This work is subject to the terms at http://dotween.demigiant.com/license.php
|
// This work is subject to the terms at http://dotween.demigiant.com/license.php
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DG.Tweening.Plugins.Core.PathCore
|
namespace DG.Tweening.Plugins.Core.PathCore
|
||||||
{
|
{
|
||||||
internal class CubicBezierDecoder : ABSPathDecoder
|
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
|
// - waypoint
|
||||||
// - IN control point
|
// - IN control point
|
||||||
// - OUT 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)
|
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;
|
int wpsLen = wps.Length;
|
||||||
if (wpsLen < 6 || wpsLen % 3 != 0) {
|
int diff = p.addedExtraStartWp ? 1 : 0;
|
||||||
Debug.LogError("CubicBezier paths must contain waypoints in multiple of 3 (1: waypoint, 2: IN control point, 3: OUT control point)");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wpsOnlyLen = wpsLen / 3;
|
// // DEBUG
|
||||||
// Store control points
|
// for (int i = 0; i < wps.Length; ++i) {
|
||||||
p.controlPoints = new ControlPoint[wpsOnlyLen];
|
// 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;
|
int cpIndex = 0;
|
||||||
for (int i = 0; i < wpsLen; i+=3) {
|
for (int i = 3 + (p.addedExtraStartWp ? 0 : 2); i < wpsLen; i+=3) {
|
||||||
p.controlPoints[cpIndex] = new ControlPoint(wps[i+1], wps[i+2]);
|
strippedWps[strippedWpIndex] = wps[i-2];
|
||||||
|
strippedWpIndex++;
|
||||||
|
p.controlPoints[cpIndex] = new ControlPoint(wps[i-1], wps[i]);
|
||||||
cpIndex++;
|
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
|
// Manage closed path
|
||||||
if (isClosedPath) {
|
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
|
// Store total subdivisions
|
||||||
p.subdivisions = wpsOnlyLen * p.subdivisionsXSegment;
|
p.subdivisions = wpsOnlyLen * p.subdivisionsXSegment;
|
||||||
@ -40,48 +89,36 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
SetTimeToLengthTables(p, p.subdivisions);
|
SetTimeToLengthTables(p, p.subdivisions);
|
||||||
// Store waypoints lengths
|
// Store waypoints lengths
|
||||||
SetWaypointsLengths(p, p.subdivisionsXSegment);
|
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
|
// 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)
|
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 tSec = (int)Math.Floor(perc * numSections);
|
||||||
int currPt = numSections - 1;
|
int currPt = numSections - 1;
|
||||||
if (currPt > tSec) currPt = tSec;
|
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 p0 = wps[currPt];
|
||||||
Vector3 b = wps[currPt];
|
Vector3 p1 = controlPoints[currPt].a;
|
||||||
Vector3 c = wps[currPt + 1];
|
Vector3 p2 = controlPoints[currPt].b;
|
||||||
Vector3 d = currPt + 2 > wps.Length - 1 ? controlPoints[1].a : wps[currPt + 2];
|
Vector3 p3 = wps[currPt + 1];
|
||||||
|
|
||||||
return .5f * (
|
float u = 1 - t;
|
||||||
(-a + 3f * b - 3f * c + d) * (u * u * u)
|
float tt = t * t;
|
||||||
+ (2f * a - 5f * b + 4f * c - d) * (u * u)
|
float uu = u * u;
|
||||||
+ (-a + c) * u
|
float uuu = uu * u;
|
||||||
+ 2f * b
|
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)
|
internal void SetTimeToLengthTables(Path p, int subdivisions)
|
||||||
@ -113,21 +150,20 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
int count = p.wps.Length;
|
int count = p.wps.Length;
|
||||||
float[] wpLengths = new float[count];
|
float[] wpLengths = new float[count];
|
||||||
wpLengths[0] = 0;
|
wpLengths[0] = 0;
|
||||||
ControlPoint[] partialControlPs = new ControlPoint[2];
|
|
||||||
Vector3[] partialWps = new Vector3[2];
|
|
||||||
for (int i = 1; i < count; ++i) {
|
for (int i = 1; i < count; ++i) {
|
||||||
// Create partial path
|
// Create partial path
|
||||||
partialControlPs[0].a = i == 1 ? p.controlPoints[0].a : p.wps[i - 2];
|
// _PartialControlPs[0].a = i == 1 ? p.controlPoints[0].a : p.wps[i - 2];
|
||||||
partialWps[0] = p.wps[i - 1];
|
_PartialControlPs[0] = p.controlPoints[i - 1];
|
||||||
partialWps[1] = p.wps[i];
|
_PartialWps[0] = p.wps[i - 1];
|
||||||
partialControlPs[1].a = i == count - 1 ? p.controlPoints[1].a : 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
|
// Calculate length of partial path
|
||||||
float partialLen = 0;
|
float partialLen = 0;
|
||||||
float incr = 1f / subdivisions;
|
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) {
|
for (int c = 1; c < subdivisions + 1; ++c) {
|
||||||
float perc = incr * c;
|
float perc = incr * c;
|
||||||
Vector3 currP = GetPoint(perc, partialWps, p, partialControlPs);
|
Vector3 currP = GetPoint(perc, _PartialWps, p, _PartialControlPs);
|
||||||
partialLen += Vector3.Distance(currP, prevP);
|
partialLen += Vector3.Distance(currP, prevP);
|
||||||
prevP = currP;
|
prevP = currP;
|
||||||
}
|
}
|
||||||
@ -137,5 +173,7 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
// Assign
|
// Assign
|
||||||
p.wpLengths = wpLengths;
|
p.wpLengths = wpLengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,12 +19,13 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
// Static decoders stored to avoid creating new ones each time
|
// Static decoders stored to avoid creating new ones each time
|
||||||
static CatmullRomDecoder _catmullRomDecoder;
|
static CatmullRomDecoder _catmullRomDecoder;
|
||||||
static LinearDecoder _linearDecoder;
|
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)
|
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 PathType type;
|
||||||
[SerializeField] internal int subdivisionsXSegment; // Subdivisions x each segment
|
[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 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 ControlPoint[] controlPoints; // Control points used by non-linear paths
|
||||||
[SerializeField] internal float length; // Unit length of the path
|
[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)
|
[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[] timesTable; // Connected to lengthsTable, used for constant speed calculations
|
||||||
[SerializeField] internal float[] lengthsTable; // Connected to timesTable, 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 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
|
Path _incrementalClone; // Last incremental clone. Stored in case of incremental loops, to avoid recreating a new path every time
|
||||||
int _incrementalIndex = 0;
|
int _incrementalIndex = 0;
|
||||||
|
|
||||||
@ -268,6 +270,10 @@ namespace DG.Tweening.Plugins.Core.PathCore
|
|||||||
if (_linearDecoder == null) _linearDecoder = new LinearDecoder();
|
if (_linearDecoder == null) _linearDecoder = new LinearDecoder();
|
||||||
_decoder = _linearDecoder;
|
_decoder = _linearDecoder;
|
||||||
break;
|
break;
|
||||||
|
case PathType.CubicBezier:
|
||||||
|
if (_cubicBezierDecoder == null) _cubicBezierDecoder = new CubicBezierDecoder();
|
||||||
|
_decoder = _cubicBezierDecoder;
|
||||||
|
break;
|
||||||
default: // Catmull-Rom
|
default: // Catmull-Rom
|
||||||
if (_catmullRomDecoder == null) _catmullRomDecoder = new CatmullRomDecoder();
|
if (_catmullRomDecoder == null) _catmullRomDecoder = new CatmullRomDecoder();
|
||||||
_decoder = _catmullRomDecoder;
|
_decoder = _catmullRomDecoder;
|
||||||
|
|||||||
@ -34,6 +34,7 @@ namespace DG.Tweening.Plugins.Options
|
|||||||
|
|
||||||
internal Quaternion startupRot; // Used to reset orientation when rewinding
|
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 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()
|
public void Reset()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -68,15 +68,25 @@ namespace DG.Tweening.Plugins
|
|||||||
int additionalWps = 0;
|
int additionalWps = 0;
|
||||||
bool hasAdditionalStartingP = false, hasAdditionalEndingP = false;
|
bool hasAdditionalStartingP = false, hasAdditionalEndingP = false;
|
||||||
|
|
||||||
// Create final wps and add eventual starting/ending waypoints
|
// Create final wps and add eventual starting/ending waypoints.
|
||||||
// if (path.wps[0] != currVal) {
|
|
||||||
if (!Utils.Vector3AreApproximatelyEqual(path.wps[0], currVal)) {
|
if (!Utils.Vector3AreApproximatelyEqual(path.wps[0], currVal)) {
|
||||||
hasAdditionalStartingP = true;
|
hasAdditionalStartingP = true;
|
||||||
additionalWps += 1;
|
additionalWps += 1;
|
||||||
}
|
}
|
||||||
if (t.plugOptions.isClosedPath && path.wps[unmodifiedWpsLen - 1] != currVal) {
|
if (t.plugOptions.isClosedPath) {
|
||||||
hasAdditionalEndingP = true;
|
Vector3 endWp = path.wps[unmodifiedWpsLen - 1];
|
||||||
additionalWps += 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;
|
int wpsLen = unmodifiedWpsLen + additionalWps;
|
||||||
Vector3[] wps = new Vector3[wpsLen];
|
Vector3[] wps = new Vector3[wpsLen];
|
||||||
@ -87,6 +97,8 @@ namespace DG.Tweening.Plugins
|
|||||||
path.wps = wps;
|
path.wps = wps;
|
||||||
|
|
||||||
// Finalize path
|
// Finalize path
|
||||||
|
path.addedExtraStartWp = hasAdditionalStartingP;
|
||||||
|
path.addedExtraEndWp = hasAdditionalEndingP;
|
||||||
path.FinalizePath(t.plugOptions.isClosedPath, t.plugOptions.lockPositionAxis, currVal);
|
path.FinalizePath(t.plugOptions.isClosedPath, t.plugOptions.lockPositionAxis, currVal);
|
||||||
|
|
||||||
t.plugOptions.startupRot = trans.rotation;
|
t.plugOptions.startupRot = trans.rotation;
|
||||||
|
|||||||
@ -996,6 +996,9 @@
|
|||||||
<member name="F:DG.Tweening.PathType.CatmullRom">
|
<member name="F:DG.Tweening.PathType.CatmullRom">
|
||||||
<summary>Curved path (which uses Catmull-Rom curves)</summary>
|
<summary>Curved path (which uses Catmull-Rom curves)</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="F:DG.Tweening.PathType.CubicBezier">
|
||||||
|
<summary><code>EXPERIMENTAL: </code>Curved path (which uses Cubic Bezier curves, where each point requires two extra control points)</summary>
|
||||||
|
</member>
|
||||||
<member name="T:DG.Tweening.Plugins.Core.PathCore.ControlPoint">
|
<member name="T:DG.Tweening.Plugins.Core.PathCore.ControlPoint">
|
||||||
<summary>
|
<summary>
|
||||||
Path control point
|
Path control point
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user