如何正确的使用Lerp In Unity

原创 2016年08月31日 13:29:32

摘要

本文探讨如何用lerp实现近似的匀速旋转,当然如果运用本文给出的方法,使用slerp则可以实现匀速旋转,并指出Unity官方lerp示例代码的一些缺陷。


现有问题

比如四元数Lerp API:

Interpolates between a and b by t and normalizes the result afterwards. The parameter t is clamped to the range [0, 1].

public static Quaternion Lerp(Quaternion a, Quaternion b, float t);

以及使用示例

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Transform from;
    public Transform to;
    public float speed = 0.1F;
    void Update() {
       transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);
    }
}
如果这样使用,会有如下几个问题值得我们注意:


1)这样的旋转不是匀速的旋转,这种是逐渐减速的旋转。

2)永远无法旋转到目标角度,可以无限的接近。

3)旋转速度与帧数相关,请注意from.rotation在变化,举例来说单位时间内移动2次2%和移动1次4%并不相同。


正确的使用方法

首先可以参考如下文章  如何正确使用lerp

这篇文章的观点和我的观点是一致的,再没看过此文之前,我并不能100%确认我想法的正确性,毕竟示例代码是Unity官方给出的。

实际上,我的项目不是基于Unity,而是基于公司自研的游戏引擎。

我的方法和链接英文提供的方法并不完全相同,以下为示例代码如下:


static f32 GetRotateScale(VEC3 speedDir,VEC3 eulerAngleLast,int dt,f32 rotateSpeed)
{

	VEC3  eulerAngleCur = speedDir.getHorizontalAngle();
	f32 deltaAngle = ABS(eulerAngleLast.getY() - eulerAngleCur.getY());
	deltaAngle = fmod(deltaAngle, 360.f);
	if (deltaAngle > 180.f) deltaAngle = 360 - deltaAngle;

	f32 scale = 1;
	if (FLOAT_EQUALS_ZERO_ROUGH(deltaAngle))
		scale = 1;
	else scale = (dt / 1000.f) * rotateSpeed / deltaAngle;
	if (scale > 1)
		scale = 1;
	return scale;
}

我解释一下函数参数。speeddir是指模型需要朝向的方向,euleranglelast是指当前模型朝向,dt就是deltaTime,rotateSpeed就是指给定的旋转速度。

函数返回值是0-1的比例。该值会传递给lerp做最终的角度旋转。

这个函数功能比较简单,根据角度差,旋转速度来设置scale,当scale等于1时,就会瞬间转到指定角度。每次旋转前需要获取下该次旋转需要的scale。

scale并不是简单的deltaTime * speed 这么简单。


总结

使用slerp可以做到完美的匀速旋转,但是并没有十分必要。实际上采用上述方法采用lerp,肉眼观察已感知不到转速的差异。

1)这是匀速旋转

2)你可以到达目标角度

3)和帧数是无关的

解决问题的方法有很多,每个人都可以有自己的想法。重要的是要先意识到问题的存在。



unity中Lerp的使用

unity中很多类都有Lerp的属性,比如Vector3.Lerp     Quaternion.Lerp  Color.Lerp  还有Slerp   用法都一样,这个属性叫做插值。 两个向量之...
  • i1tws
  • i1tws
  • 2016年11月25日 21:35
  • 1300

Unity3D中的线性插值Lerp()函数解析

在unity3d中经常用线性插值函数Lerp()来在两者之间插值,两者之间可以是两个材质之间、两个向量之间、两个浮点数之间、两个颜色之间,其函数原型如下: 1.Material.Le...
  • u014659211
  • u014659211
  • 2016年05月26日 14:54
  • 11906

unity中mathf.Lerp的运用

在unity3d中经常用线性插值函数Lerp()来在两者之间插值,两者之间可以是两个材质之间、两个向量之间、两个浮点数之间、两个颜色之间,其函数原型如下: 1.Material.Lerp 插值func...
  • Fenglele_Fans
  • Fenglele_Fans
  • 2017年09月29日 09:40
  • 365

Unity3D中的线性插值Lerp()函数解析

  • 2015年12月03日 19:06
  • 1.02MB
  • 下载

关于Lerp插值的基本原理和在Unity中的应用

简单的讲解一下其实也很简单的Lerp插值运算。通过这个讲解,希望能传达一种积极的严谨的程序思维。...
  • u010133610
  • u010133610
  • 2017年03月22日 12:35
  • 1867

unity Mathf Lerp 的用法

Lerp 可以看成是一种进度
  • JAROD_JIANGHE
  • JAROD_JIANGHE
  • 2016年09月18日 14:32
  • 5561

[Unity3D] MoveTowards、Lerp、Slerp

MoveTowards、Lerp、Slerp 这三个函数相信大家经常遇到,这些都是在做一些过渡操作时需要用到的,那么它们间的具体差别是什么呢?其实要搞清楚它们的区别,只要仔细看官方说明,明白它们的具体...
  • andyhebear
  • andyhebear
  • 2016年07月04日 09:18
  • 5502

什么是Shader里的lerp

float lerp(float a, float b, float w) { return a + w*(b-a); }
  • sgnyyy
  • sgnyyy
  • 2016年08月31日 23:21
  • 2300

unity 关于Rotation和Quaternion的一些问题(欧拉角与四元数,lerp与slerp)

当我们使用unity的时候,面对一个物体,一个不可避免的问题就是:控制物体的旋转。 unity的Transform组件的第二个属性Rotation为我们提供控制物体旋转的功能。在一个物体的Inspec...
  • zhr_hadoop
  • zhr_hadoop
  • 2016年04月22日 15:51
  • 4600

摄像机跟随之Vector3.Lerp(start,end,t)方法

插值是数学上的一个概念,在这里用公式表示就是:from + (to - from) * t;这也就是Lerp的返回值(用这个公式分别算出x,y,z)。 static function Lerp (f...
  • XYK0318
  • XYK0318
  • 2016年04月25日 09:29
  • 1278
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何正确的使用Lerp In Unity
举报原因:
原因补充:

(最多只允许输入30个字)