Skip to content

Commit d996fd9

Browse files
committed
EasedLerp functions and CalculateCentroid
1 parent 6523b02 commit d996fd9

File tree

7 files changed

+326
-17
lines changed

7 files changed

+326
-17
lines changed

Examples/MathHelperExamples.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ void Awake()
1313
{
1414
MappingExamples();
1515
AnglesExamples();
16+
17+
// Checks what calling the same EasedLerp from 0 to 1 and a factor of 75%
18+
// with 1, 10, 100, 1000 or 10000 FPS would return after one second.
19+
CheckEasedLerp(1); // => 0.75
20+
CheckEasedLerp(10); // => 0.7499999
21+
CheckEasedLerp(100); // => 0.7499999
22+
CheckEasedLerp(1000); // => 0.7499995
23+
CheckEasedLerp(10000); // => 0.7500508
1624
}
1725

1826
void Update()
@@ -70,9 +78,24 @@ private void EasedLerpFactorExample()
7078
// Set the runner position to the mouse pointer
7179
runner.position = mousePositionWorld;
7280

73-
// Each second, move the follower 75% of the remaining distance to the runner
74-
float t = MathHelper.EasedLerpFactor(0.75f);
75-
follower.position = Vector3.Lerp(follower.position, mousePositionWorld, t);
81+
// Move the follower 75% of the remaining distance to the runner per second
82+
follower.position = UnityHelper.EasedLerpVector3(follower.position, runner.position, 0.75f);
83+
84+
// ...which is the same as:
85+
86+
//float t = MathHelper.EasedLerpFactor(0.75f);
87+
//follower.position = Vector3.Lerp(follower.position, mousePositionWorld, t);
88+
}
89+
90+
void CheckEasedLerp(int steps)
91+
{
92+
var dt = 1f / steps;
93+
94+
var currentValue = 0f;
95+
for (var i = 0; i < steps; i++)
96+
currentValue = MathHelper.EasedLerp(currentValue, 1f, 0.75f, dt);
97+
98+
Debug.LogFormat("CheckEasedLerp({0}): {1}", steps, currentValue);
7699
}
77100
}
78101
}

Examples/UnityHelperExamples.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ public class UnityHelperExamples : MonoBehaviour
1414
void Awake()
1515
{
1616
TransformVectorColorExamples();
17+
CentroidExample();
1718
Vector2RotationExamples();
1819
GameObjectExamples();
1920
RectExamples();
2021
PlayerPrefsExample();
2122
CapsuleCastExample();
2223
RandomExamples();
2324
OtherExamples();
25+
26+
// You can find an example for eased lerping in MathHelperExamples.EasedLerpFactorExample()
2427
}
2528

2629
void TransformVectorColorExamples()
@@ -49,6 +52,18 @@ void TransformVectorColorExamples()
4952
enemyIndicator.CopyPositionAndRotatationFrom(someEnemyTransform);
5053
}
5154

55+
private void CentroidExample()
56+
{
57+
Vector3[] list = {
58+
new Vector3(-5, 10, 12),
59+
new Vector3(55, 32, 10),
60+
new Vector3(85, -40, 80)
61+
};
62+
63+
// Calculates the geometric center (the average) of the input list.
64+
Debug.Log("Centroid: " + list.CalculateCentroid()); // => Centroid: (45.0, 0.7, 34.0)
65+
}
66+
5267
void Vector2RotationExamples()
5368
{
5469
// Create a length 1 Vector2 pointing 40 degrees away from (1.0, 0.0)

MathHelper/MathHelper.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public static float NormalizeAngleDeg180(float angle)
125125

126126
#endregion
127127

128-
#region Miscellaneous
128+
#region Framerate-Independent Lerping
129129

130130
/// <summary>
131131
/// Provides a framerate-independent t for lerping towards a target.
@@ -147,8 +147,8 @@ public static float NormalizeAngleDeg180(float angle)
147147
/// currentValue = Mathf.Lerp(currentValue, 1f, 0.95f);
148148
///
149149
/// every frame provides an easy way of eased lerping without tracking elapsed time or the
150-
/// starting value, but since it's called every frame, the actual speed changes the higher
151-
/// the framerate is.
150+
/// starting value, but since it's called every frame, the actual traversed distance per
151+
/// second changes the higher the framerate is.
152152
///
153153
/// This function replaces the lerp T to make it framerate-independent and easier to estimate.
154154
///
@@ -165,6 +165,29 @@ public static float EasedLerpFactor(float factor, float deltaTime = 0f)
165165
return 1 - Mathf.Pow(1 - factor, deltaTime);
166166
}
167167

168+
/// <summary>
169+
/// Framerate-independent eased lerping to a target value, slowing down the closer it is.
170+
///
171+
/// If you call
172+
///
173+
/// currentValue = MathHelper.EasedLerp(currentValue, 1f, 0.75f);
174+
///
175+
/// each frame (e.g. in Update()), starting with a currentValue of 0, then after 1 second
176+
/// it will be approximately 0.75 - which is 75% of the way between 0 and 1.
177+
///
178+
/// Adjusting the target or the percentPerSecond between calls is also possible.
179+
/// </summary>
180+
/// <param name="current">The current value.</param>
181+
/// <param name="target">The target value.</param>
182+
/// <param name="percentPerSecond">How much of the distance between current and target should be covered per second?</param>
183+
/// <param name="deltaTime">How much time passed since the last call.</param>
184+
/// <returns>The interpolated value from current to target.</returns>
185+
public static float EasedLerp(float current, float target, float percentPerSecond, float deltaTime = 0f)
186+
{
187+
var t = EasedLerpFactor(percentPerSecond, deltaTime);
188+
return Mathf.Lerp(current, target, t);
189+
}
190+
168191
#endregion
169192
}
170193
}

MathHelper/README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,34 @@ There are essentially two ways of lerping a value over time: linear (constant sp
1010

1111
For linear lerping (and most of the easing functions), you need to track the start and end positions and the time that elapsed.
1212

13-
Calling something like `currentValue = Mathf.Lerp(currentValue, 1f, 0.95f);` every frame provides an easy way of eased lerping without tracking elapsed time or the starting value, but since it's called every frame, the actual speed changes the higher the framerate is.
13+
Calling something like `currentValue = Mathf.Lerp(currentValue, 1f, 0.95f);` every frame provides an easy way of eased lerping without tracking elapsed time or the starting value, but since it's called every frame, the actual traversed distance per second changes the higher the framerate is.
1414

1515
EasedLerpFactor replaces the lerp parameter t to make it framerate-independent and easier to estimate.
1616

1717
You can find more information about the formula used [here](https://www.scirra.com/blog/ashley/17/using-lerp-with-delta-time).
1818

19+
You can use `MathHelper.EasedLerpFactor` to get the t used for a lerp or call `MathHelper.EasedLerp`, `UnityHelper.EasedLerpVector2`, `UnityHelper.EasedLerpVector3`, `UnityHelper.EasedLerpVector4` or `UnityHelper.EasedLerpColor` directly.
20+
1921
![EasedLerpFactorExample Editor Screenshot](https://raw.githubusercontent.com/TobiasWehrum/unity-utilities/master/_Images/EasedLerpFactorExample.gif)
2022

2123
```C#
22-
// Get the world position of the mouse pointer
23-
Vector3 mousePositionWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
24-
mousePositionWorld.z = 0f;
24+
void Update()
25+
{
26+
// Get the world position of the mouse pointer
27+
Vector3 mousePositionWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
28+
mousePositionWorld.z = 0f;
29+
30+
// Set the runner position to the mouse pointer
31+
runner.position = mousePositionWorld;
32+
33+
// Move the follower 75% of the remaining distance to the runner per second
34+
follower.position = UnityHelper.EasedLerpVector3(follower.position, runner.position, 0.75f);
2535

26-
// Set the runner position to the mouse pointer
27-
runner.position = mousePositionWorld;
36+
// ...which is the same as:
2837
29-
// Each second, move the follower 75% of the remaining distance to the runner
30-
float t = MathHelper.EasedLerpFactor(0.75f);
31-
follower.position = Vector3.Lerp(follower.position, mousePositionWorld, t);
38+
//float t = MathHelper.EasedLerpFactor(0.75f);
39+
//follower.position = Vector3.Lerp(follower.position, mousePositionWorld, t);
40+
}
3241
```
3342

3443
### Mapping

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ You can also just use selected scripts, but you should check the "Dependencies"
3131
The class documentation is available [here](http://tobiaswehrum.github.io/UnityUtilities/html/annotated.html).
3232

3333
## Changelog
34-
* 2016-10-20: Added [MathHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/MathHelper). Added randomization helper methods to [UnityHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/UnityHelper).
34+
* 2016-10-23: Fixed bugs/improved [Singleton](https://github.com/TobiasWehrum/unity-utilities/tree/master/Singleton). Added EasedLerp methods for float in [MathHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/MathHelper) and Vector2, Vector3 and Color in [UnityHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/UnityHelper).
35+
* 2016-10-22: Added [MathHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/MathHelper). Added randomization helper methods to [UnityHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/UnityHelper).
3536
* 2016-07-03: Added [MeshCreator](https://github.com/TobiasWehrum/unity-utilities/tree/master/MeshCreator).
3637
* 2016-06-19: Added [XmlHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/XmlHelper).
3738
* 2016-06-08: Added [UnityHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/UnityHelper).

UnityHelper/README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,55 @@ Color halfTransparentColor = GetComponent<Renderer>().sharedMaterial.color.Chang
3131
enemyIndicator.CopyPositionAndRotatationFrom(someEnemyTransform);
3232
```
3333

34+
### Framerate-Independent Eased Lerping
35+
36+
There are essentially two ways of lerping a value over time: linear (constant speed) or eased (e.g. getting slower the closer you are to the target, see http://easings.net.)
37+
38+
For linear lerping (and most of the easing functions), you need to track the start and end positions and the time that elapsed.
39+
40+
Calling something like `currentValue = Mathf.Lerp(currentValue, 1f, 0.95f);` every frame provides an easy way of eased lerping without tracking elapsed time or the starting value, but since it's called every frame, the actual traversed distance per second changes the higher the framerate is.
41+
42+
EasedLerpFactor replaces the lerp parameter t to make it framerate-independent and easier to estimate.
43+
44+
You can find more information about the formula used [here](https://www.scirra.com/blog/ashley/17/using-lerp-with-delta-time).
45+
46+
You can use `MathHelper.EasedLerpFactor` to get the t used for a lerp or call `MathHelper.EasedLerp`, `UnityHelper.EasedLerpVector2`, `UnityHelper.EasedLerpVector3`, `UnityHelper.EasedLerpVector4` or `UnityHelper.EasedLerpColor` directly.
47+
48+
![EasedLerpFactorExample Editor Screenshot](https://raw.githubusercontent.com/TobiasWehrum/unity-utilities/master/_Images/EasedLerpFactorExample.gif)
49+
50+
```C#
51+
void Update()
52+
{
53+
// Get the world position of the mouse pointer
54+
Vector3 mousePositionWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
55+
mousePositionWorld.z = 0f;
56+
57+
// Set the runner position to the mouse pointer
58+
runner.position = mousePositionWorld;
59+
60+
// Move the follower 75% of the remaining distance to the runner per second
61+
follower.position = UnityHelper.EasedLerpVector3(follower.position, runner.position, 0.75f);
62+
63+
// ...which is the same as:
64+
65+
//float t = MathHelper.EasedLerpFactor(0.75f);
66+
//follower.position = Vector3.Lerp(follower.position, mousePositionWorld, t);
67+
}
68+
```
69+
70+
### Get the centroid from an array/list of Vector2/3/4
71+
72+
```C#
73+
Vector3[] list = {
74+
new Vector3(-5, 10, 12),
75+
new Vector3(55, 32, 10),
76+
new Vector3(85, -40, 80)
77+
};
78+
79+
// Calculates the geometric center (the average) of the input list.
80+
Debug.Log("Centroid: " + list.CalculateCentroid()); // => Centroid: (45.0, 0.7, 34.0)
81+
```
82+
3483
### Vector2 Rotation
3584

3685
```C#
@@ -150,4 +199,4 @@ bool hitSomething = Physics.CapsuleCast(point1, point2, radius, Vector3.forward,
150199

151200
## Dependencies
152201

153-
None.
202+
* [MathHelper](https://github.com/TobiasWehrum/unity-utilities/tree/master/MathHelper)

0 commit comments

Comments
 (0)