Unity中指数函数实现越来越快或者越来越慢的变化控制

       有时需要这样的效果:UI的数字从一个值变化到另一个值,是一个不断增大的过程,而且是一种由慢变快的过程。就实现这种效果来说,可以DoTween这类组件实现,也可以用unity的曲线AnimationCurve实现。这里说的是另外一种方式,就是自己实现指数增长变快的过程。

       指数曲线和函数,中学就学过。它一条很陡峭的曲线,大白话就是越来愈大,而且变的越来越快。

Unity中指数函数实现越来越快或者越来越慢的变化控制_第1张图片

  我们可以先把变化区间从指数公式计算出来,当时y的开始和结束,x轴看成时间。然后用累计时间在y的开始和结束之间做插值,这里给出两段代码,分别用到初始化和Update中

        //变化范围
        int change = target - orgNum;
        //指数, 指数范围即是时间范围
        beginExp = 0; //e^beginExp =1
        endExp = Mathf.Log(change); // e^endExp = change
        currExp = Mathf.Lerp(beginExp, endExp, currveVale);
        currNum = orgNum + (int)Mathf.Exp(currExp);

      这里第二段代码用在update里,没有直接使用插值结果,而是让用户有更多的选择,用一条曲线让用户选择,再去控制这个变化趋势。比如,我想比指数变快,还快。

      有了越来越快的需求,也就有越来越慢的需求。我们可以用指数函数的反函数对数函数实现。原理差不多,只是在用对数实现时候,一开始要用到指数函数,如果数比较大时,会越界。就像我们能用等差数列求和来检查一个数字序列是不是等差数列一样,数学上是可以的,当数字很大时,到了计算机上就会越界。具体做法做了scale处理,最大只可能计算e^10,不会越界
根据公式 ln(e^x) = x*ln(e) 且 ln(e)=1, 用scale后的x(用x'表示) 带入 ln(e^x') = x'*ln(e) = x' 。这样就能完全可以在计算对数后,用scale回去。

        //变化范围
        int change = target - orgNum;
        //把变化值缩小,防止Exp越界,并记录scale
        scale = (float)change / 10f;
        float scaleChange = change / scale;
        beginLog = 1;
        endLog = Mathf.Exp(scaleChange);
        currLog = Mathf.Lerp(beginLog, endLog, currveVale);
        currNum = orgNum + (int)(Mathf.Log(currLog) * scale);

完整代码实现 下载链接

 

你可能感兴趣的:(Unity3D.杂项)