How to Lerp like a pro
来源:互联网 发布:情趣用品淘宝店简介 编辑:程序博客网 时间:2024/05/16 12:06
I see this sort of thing far too often:
transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime);
The person posting it is usually convinced that Vector3.Lerp
is “broken”, but the real problem is that they’re not using it correctly.
Lerp, short for “linear interpolation” does one very simple thing: given two values, x
and y
, it returns a value that is t
percent between them. If you expect the output to change, the arguments you pass in need to reflect that!
In the example above, it doesn’t make sense to just pass in Time.deltaTime
, because that’s only the time that passed during the most recent frame. If your game is running at a constant 50fps, that’s always going to be 0.02
.
We’ll get better results if we let that timer accumulate over multiple frames.
Something like this should get the point across:
public
class
LerpExample : MonoBehaviour {
float
lerpTime = 1f;
float
currentLerpTime;
float
moveDistance = 10f;
Vector3 startPos;
Vector3 endPos;
protected
void
Start() {
startPos = transform.position;
endPos = transform.position + transform.up * moveDistance;
}
protected
void
Update() {
//reset when we press spacebar
if
(Input.GetKeyDown(KeyCode.Space)) {
currentLerpTime = 0f;
}
//increment timer once per frame
currentLerpTime += Time.deltaTime;
if
(currentLerpTime > lerpTime) {
currentLerpTime = lerpTime;
}
//lerp!
float
perc = currentLerpTime / lerpTime;
transform.position = Vector3.Lerp(startPos, endPos, perc);
}
}
You could create an empty scene, drop in a cube, attach this script, and see it in action.
The variable perc
is used where Time.deltaTime
used to be. What is perc
? It’s a number between 0
and 1
, representing our progress through the Lerp.
If you’re curious, check the result if you change lerpTime
or moveDistance
.
Lerp everything
Unity provides helper functions for interpolating many different values.
Mathf.Lerp
Vector3.Lerp
Color.Lerp
At the end of the day, though, Mathf.Lerp is all you need; the others are just convenience methods on top of that. It’s easy enough to write your own Lerp function for any class or data you might need to interpolate.
In the specific case of quaternions, which Unity uses to represent rotation, there’s even a Slerp or “Spherical Lerp”.
Any time you have two values, and you’d like to smoothly transition between them? Interpolation is your friend!
Beyond Lerp
What if we passed Lerp a t
that wasn’t just a straight percentage? What if, instead of a straight line graphed between two points, we wanted some sort of curve? Our input must remain between 0
and 1
, but there are many functions that accomplish that.
For example, we could “ease out” with sinerp:
float t = currentLerpTime / lerpTime;t = Mathf.Sin(t * Mathf.PI * 0.5f);
Or we could “ease in” with coserp:
t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f)
We could even create exponential movement:
t = t*t
Multiplying t
by itself has an interesting quirk: so long as t
is between 0
and 1
, multiplying t
by itself any number of times will always produce a number that is also between 0
and 1
.
Smoothstep
The multiplication property mentioned above is the core concept behind some interpolation methods which ease in and ease out, such as the famous“smoothstep” formula:
t = t*t * (3f - 2f*t)
Or my personal favorite, “smootherstep”:
t = t*t*t * (t * (6f*t - 15f) + 10f)
So smooth! (Couldn’t resist.)
Many of these extra formulas I’ve mentioned aren’t included with Unity, but that just gives you the freedom to use any function you can find or create.
Make it breathe
What about a Lerp that never ends?
Robert Yang once said, “Sometimes I wish I could animate every single thing in my game with a sine wave.”
Some games introduce a slight “head bob” while the player is running. Other games need a gentle bob for the main menu camera. I’ve seen lights that “snore”, fading in and out. Whatever the case, I just want to point out how fantastically useful wave functions can be — their input domain is infinite, so they never have to end, and their output range is both narrow and constant, so they’re easy to control.
For example, this script makes an object slowly move up and down, according to a sine wave:
public
class
BreatheSimple : MonoBehaviour {
Vector3 startPos;
protected
void
Start() {
startPos = transform.position;
}
protected
void
Update() {
float
distance = Mathf.Sin(Time.timeSinceLevelLoad);
transform.position = startPos + Vector3.up * distance;
}
}
Adjusting the sine wave gives us more control:
public
class
Breathe : MonoBehaviour {
Vector3 startPos;
public
float
amplitude = 10f;
public
float
period = 5f;
protected
void
Start() {
startPos = transform.position;
}
protected
void
Update() {
float
theta = Time.timeSinceLevelLoad / period;
float
distance = amplitude * Mathf.Sin(theta);
transform.position = startPos + Vector3.up * distance;
}
}
Amplitude controls how far the object moves; period controls how quickly it does so.
A player’s head bob might call for small amplitude and a short period. A menu camera’s slow breathing might call for an extremely long period, or movement on multiple axes at varying rates.
As long as you can sort out the math, you can get whatever behavior you want.
What happens if you take only the absolute value of the sine wave? Upward-only bouncing.
What happens in you clamp the sine wave’s output between 0
and 1
? Upward-only bouncing with a pause between bounces. Can you see why? Draw the clamped curve yourself and it should become clear.
What if you clamped that wave’s output between 0.6
and 1
? Would you get a sort of “throb” motion? Could that be useful to scale an alert in your UI?
If you want to get really fancy, you could even use an animation curve to manage your Lerp params.
I’ve written some pretty esoteric curve and wave functions. Don’t be afraid to mix it up.
In closing
Lerp is an easy and powerful function with many applications.
One of the first plugins I ever wrote was a camera manager that interpolates between various zooms and positions. I’ve also used interpolation to manage material parameters, UI animation, physical forces, audio volume, simple cutscenes, and more.
This is one of those hammers that turns up more and more often, once you know how to use it.
If you don’t want to write a lot of code, or want a head start, plugins like iTween, GoKit, or Hotween add lots of extra interpolation support to Unity.
原文地址:
https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/
- How to Lerp like a pro
- Hack Like a Pro: How to Hack a Computer & Spy on Anyone, Part 1
- Hack Like a Pro: How to Remotely Install a Keylogger onto Your Girlfriend's Computer
- Hack Like a Pro: How to Kill and Disable Antivirus Software on a Remote PC
- Hack Like a Pro: How to Crack Passwords, Part 3 (Using Hashcat)
- How to Think Like a Computer Scientist
- How to Think Like a Computer Scientist
- How to code like a hacker
- HOW TO MAKE A TROJAN LOOK LIKE A JPG
- Python入门读物摘要--How to think like a csor
- How to design a tabpanel in blackberry like iPhone style
- How to Make a Game Like Candy Crush
- 《How to think like a designer》思悟总结
- use vim like a pro
- Hack Like a Pro: Using Nexpose to Scan for Network & System Vulnerabilities
- How to Make a Gesture-Driven To-Do List App Like Clear: Part 1/3
- 正在翻译HOW TO THINK LIKE A COMPUTE SCIENTIST ——LEARN PYTHON
- Using IP Instances with VLANs or How to Make a Few NICs Look Like Many
- HTML :input text 的事件及方法
- 3-6q环视之显示,ipu的注册
- HLJUOJ1127 &&HDU2049(错排公式+排列组合)
- 1021. Deepest Root (25)
- 微信电话本通话费多少?
- How to Lerp like a pro
- SQLite并发访问出现The database file is locked , database is locked
- Android 图像处理(类型转换,比例缩放,倒影,圆角)
- 利用socket实现客户端与服务器端聊天
- android:关于主工程和library project
- 代码审查和不良编程习惯
- Oracle用户Profile详解
- SVN使用过程中出现的错误记录(一)
- 林丹 - 没有人想永远输给你