Unity中的平滑过渡方法了解

只是刚入门,通过代码以及文档比较一下异同点,以后遇到问题方便选择.

Mathf.Lerp

// UnityEngine.Mathf
/// <summary>
///   <para>Linearly interpolates between a and b by t.</para>
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation value between the two floats.</param>
/// <returns>
///   <para>The interpolated float result between the two float values.</para>
/// </returns>
public static float Lerp(float a, float b, float t)
{
	return a + (b - a) * Mathf.Clamp01(t);
}

结果是a + (b - a) * Mathf.Clamp01(t),将返回【a,b】之间的数字,参数t表示插值,会在被调用之后由Mathf.Clamp01限制在【0,1】之间

Mathf.LerpUnclamped

// UnityEngine.Mathf
/// <summary>
///   <para>Linearly interpolates between a and b by t with no limit to t.</para>
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation between the two floats.</param>
/// <returns>
///   <para>The float value as a result from the linear interpolation.</para>
/// </returns>
public static float LerpUnclamped(float a, float b, float t)
{
	return a + (b - a) * t;
}

不限制t的范围,所以返回值不限制在【a,b】之间

Mathf.MoveTowards

感觉Lerp和MoveTowards基本一样,如果是在update中的匀速运动

经过测试没发现有什么区别.

// UnityEngine.Mathf
/// <summary>
///   <para>Moves a value current towards target.</para>
/// </summary>
/// <param name="current">The current value.</param>
/// <param name="target">The value to move towards.</param>
/// <param name="maxDelta">The maximum change that should be applied to the value.</param>
public static float MoveTowards(float current, float target, float maxDelta)
{
	float result;
	if (Mathf.Abs(target - current) <= maxDelta)
	{
		result = target;
	}
	else
	{
		result = current + Mathf.Sign(target - current) * maxDelta;
	}
	return result;
}
   void FixedUpdate()
    {
        t += Time.fixedDeltaTime;
        Debug.Log("<color=red>Lerp is"+Mathf.Lerp(1,5,t)+"</color>");
        current = Mathf.MoveTowards(current, 5, (5-1)*Time.fixedDeltaTime);
        Debug.Log("<color=green>MoveTowards is"+current+"</color>");
    }

http://gamedev.stackexchange.com/questions/49155/lerp-vs-vector-math-one-better-than-the-other

Velocity and lerping are for different purposes. Lerping is great when you
know
you‘re going to end at the target in a given time; it‘s good for many UI animations, for example.

Use velocity when what you have is the speed of movement and the intent
to get to a target at that constant speed. Using the velocity let‘s you
smoothly change directions mid-course, slow down or speed up, etc. I
had a place I was lerping vectors
and changed to steering (velocty/force) because then I could make
objects twist and "dodge" each other if they crossed paths.

In general, use lerp for static animations, use velocity (or full physics) for in-game character/object movement.

关于两者区别,摘了一点,主要是Lerp和MoveToward的使用场景可能会有各自的方便之处

Vctor3.Slerp

// UnityEngine.Vector3
/// <summary>
///   <para>Spherically interpolates between two vectors.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="t"></param>
[ThreadAndSerializationSafe]
public static Vector3 Slerp(Vector3 a, Vector3 b, float t)
{
	Vector3 result;
	Vector3.INTERNAL_CALL_Slerp(ref a, ref b, t, out result);
	return result;
}

过渡方向和大小

    void Start () {
            Debug.Log(Vector3.Slerp(Vector3.forward, Vector3.right*2, 0.5f));
            Debug.Log(new Vector3(0.5f,0,0.5f).normalized*((1+2f)/2));
        }

具体计算方法应该是先将a,b两个向量单位化,新向量方向,然后计算通过模和取平均值,计算大小

LerpAngle

    /// <summary>
    ///   <para>Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <param name="t"></param>
    public static float LerpAngle(float a, float b, float t)
    {
        float num = Mathf.Repeat(b - a, 360f);
        if (num > 180f)
        {
            num -= 360f;
        }
        return a + num * Mathf.Clamp01(t);
    }

注意计算的结果可能为负数或者大于360,需要自行转换

SmoothDamp

    // UnityEngine.Mathf
    public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, [DefaultValue("Mathf.Infinity")] float maxSpeed, [DefaultValue("Time.deltaTime")] float deltaTime)
    {
        smoothTime = Mathf.Max(0.0001f, smoothTime);
        float num = 2f / smoothTime;
        float num2 = num * deltaTime;
        float num3 = 1f / (1f + num2 + 0.48f * num2 * num2 + 0.235f * num2 * num2 * num2);
        float num4 = current - target;
        float num5 = target;
        float num6 = maxSpeed * smoothTime;
        num4 = Mathf.Clamp(num4, -num6, num6);
        target = current - num4;
        float num7 = (currentVelocity + num * num4) * deltaTime;
        currentVelocity = (currentVelocity - num * num7) * num3;
        float num8 = target + (num4 + num7) * num3;
        if (num5 - current > 0f == num8 > num5)
        {
            num8 = num5;
            currentVelocity = (num8 - num5) / deltaTime;
        }
        return num8;
    }

http://devblog.aliasinggames.com/smoothdamp

http://devblog.aliasinggames.com/how-to-lerp-properly/

http://devblog.aliasinggames.com/lerp-in-unity/

这里有篇关于SmoothDamp的文章,抽空再仔细拜读.

时间: 2024-10-26 04:16:35

Unity中的平滑过渡方法了解的相关文章

(转)Unity中protobuf的使用方法

在移动手机游戏开发中,目前Unity3D已成为比较主流的开发技术. 那么对于客户端服务器协议的打解包,我们有3中常用的处理方式: 1.自定义结构体:在协议中直接传输代码中自定义的结构体:这种方式的坏处是极大的增加了重复性的工作量,并且不能实现协议前后向兼容,可扩展性差: 2.json.xml等文本协议格式: 使用json.xml等文本协议作为协议格式:这种方式的好处是易于开发,方便协议前后向兼容和扩展,缺点是不能序列化,数据量大,浪费带宽: 3.推荐使用的方式: protobuf协议打解包方式:

3D语音天气球——在Unity中使用Android语音服务

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3D语音天气球(源码分享)--创建可旋转的3D球 二:通过天气服务,从网络获取时实天气信息并动态生成"3D球":3D语音天气球(源码分享)--通过天气服务动态创建3D球 三:Android语音服务和Unity的消息传递 四:Unity3D端和Android端的结合 前两篇文章已经介绍了如何创

Unity中的协程(一)

这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn.net/huang9012/article/details/38492937 协程介绍 在Unity中,协程(Coroutines)的形式是我最喜欢的功能之一,几乎在所有的项目中,我都会使用它来控制运动,序列,以及对象的行为.在这个教程中,我将会说明协程是如何工作的,并且会附上一些例子来介绍它的用法

unity中三种调用其他脚本函数的方法

第一种,被调用脚本函数为static类型,调用时直接用  脚本名.函数名().很不实用-- 第二种,GameObject.Find("脚本所在物体名").SendMessage("函数名");  此种方法可以调用public和private类型函数 第三种,GameObject.Find("脚本所在物体名").GetComponent<脚本名>().函数名();此种方法只可以调用public类型函数 unity中三种调用其他脚本函数的

C#开发Unity游戏教程之Unity中方法的参数

C#开发Unity游戏教程之Unity中方法的参数 Unity的方法的参数 出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号“( )”,有意义吗?看起来最多也就是起个快速识别方法的作用吧.既然C#的语法规定方法就应该这么写,肯定是有一定道理的.如果是上升到战略意义的道理,连作者也不是很明白,但是作者知道这对括号里可以添加“参数”. Unity中参数的作用 要说明参数的作用,就必须从方法说起.方法可以处理变量中的数据,进而影响游戏对象的行为逻辑,这是本章前面一直在强调的.

用体渲染的方法在Unity中渲染云

最近在知乎上看到一篇文章讲云层的渲染(https://zhuanlan.zhihu.com/p/34836881?utm_medium=social&utm_source=qq) 原文简单的讲了噪声生成云体的办法,以及一个光照模型. 看了之后很感兴趣,加上本科毕设做的就是体渲染,于是打算在unity里山寨一个出来. 原原文(知乎上的文章引用的文章)是2015年地平线黎明时分制作团队的一个talk(http://advances.realtimerendering.com/s2015/The%20

Unity SLua 如何调用Unity中C#方法

1.原理 就是通常在Lua框架中所说的,开放一个C#的web接口,或者叫做在Slua框架中注册函数. 2.作用 在Lua中调用C#中的方法,这个是在做热更新中很常用的一种方法,无论是slua,还是lua,都差不多.这里,我拿slua举例. 3.实际运用 举例:如何在Slua中打印Log 原理:其实是slua通过调用C#中的Debug.Log方法实现的打印,并不是说是lua中的打印方法起到作用. 步骤: 首先,既然是Lua调用C#中的方法,这里自定义写一个打印log的方法. 1 2 3 4 5 6

Unite 2018 | 《崩坏3》:在Unity中实现高品质的卡通渲染(下)

http://forum.china.unity3d.com/thread-32273-1-1.html 今天我们继续分享米哈游技术总监贺甲在Unite Beijing 2018大会上的演讲<在Unity上实现高品质卡通渲染的效果>下篇,上篇请点击此处阅读. 下面为演讲内容: 接下来我们就来介绍一下头发的渲染.头发是卡通渲染角色较为重要且独特的部分.我们想要实现根据光源动态变化的高光和阴影渐变,并且这个实现还应具备直观的所见即所得的色彩调节能力. 和皮肤的材质一样,对于头发的漫反射渲染我们同样

【Unity编程】Unity中关于四元数的API详解

Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计算Unity旋转.它们计算紧凑高效,不受万向节锁的困扰,并且可以很方便快速地进行球面插值. Unity内部使用四元数来表示所有的旋转. Quaternion是基于复数,并不容易直观地理解. 不过你几乎不需要访问或修改单个四元数参数(x,y,z,w); 大多数情况下,你只需要获取和使用现有的旋转(例如来自"Transform"),或者用四元数来构造新的旋转(例如,在两次旋转之间平滑插入). 大