• 如何正确的使用Lerp In Unity


    摘要

    本文探讨如何用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)和帧数是无关的

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

  • 相关阅读:
    selenium server在页面加载超时浏览器与driver通信失败时的妙用
    selenium并行的使用
    selenium代理
    selenium鼠标拖动
    做事要是专业
    selenium select 标签选中
    从字符串中提取数字
    selenium中Alter等弹出对话框的处理
    Selenium资料
    P2048 [NOI2010]超级钢琴 (RMQ,堆)
  • 原文地址:https://www.cnblogs.com/tangzhenqiang/p/5825565.html
Copyright © 2020-2023  润新知