用AnimationCurve制作Tween动画

因为制作的UI 的下拉菜单Tween,需要在结束后暂停游戏(timeScale=0),
理所当然用的DoTween插件,其拥有一个OnComplete事件方法,可以在Tween动画播放完毕后调用;
但是由于未知原因(BUG?),只要OnComplete函数中写了 “timeScale=0”,就会出现Tween动画反复播放两次,才会调用OnComplete暂停游戏,因此自己写了一个简单的tween动画;

通过查阅API,可以运用其中的AnimationCurve (动画曲线)来任意设置我们想要的动画,
如下定义:

public AnimationCurve curveTest;

就能够在Inspector中设置曲线,如下图(曲线尽量设置为x:y都为1的曲线)

这里写图片描述

此曲线表示时间与对应的路程点(1表示到达终点)

然后通过协程控制动画运行,在开始协程时记录上起始时间点和记录运行时间,
除以总路程时间,换算得到(0-1)之间的小数比值,即X时间轴的值,再通过AnimationCurve 的Evaluate方法获取对应的Y轴值(当前运动点与起点的距离比值), 通过乘以总路程就能换算出当前帧目标应该运动的位置.

当然还有反向播放的动画,其协程代码会稍有不同;

以及当未播放完当前动画立即逆向播放动画的功能实现;

哦,还有tween的种类切换,由于代码能力捉急,所以只有通过if else来判断枚举状态

具体参见下面的代码:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;



public class Test2_Curve : MonoBehaviour
{
    public enum Tweenkind { RectTransform,Transform}
    public Tweenkind tweenKind;
    RectTransform rectTransform;

    public AnimationCurve curveTest;

    public Vector3 StartPoint;//开始位置
    public Vector3 EndPoint;//结束位置
    Vector3 moveLength;//初始化时算出总行程

    float value_X = 0;//更新每时刻的X轴时间值
    public float TimeClamp;//运行时间

   // public float curveX_AxisValue;//记录当前帧时间轴值的大小

    void Start ()
    {
        moveLength = EndPoint - StartPoint;

        if(tweenKind == Tweenkind.RectTransform)
            rectTransform = this.GetComponent<RectTransform>();
    }

    void Update ()
    {
       //if(Input.GetKeyDown(KeyCode.RightArrow))
    //    {
    //        Play();
    //    }
    //   if (Input.GetKeyDown(KeyCode.LeftArrow))
    //    {
    //        PlayReverse();
    //    }
    }

   public void Play()
    {
        StopAllCoroutines();
        StartCoroutine(StartToEnd());
    }

   public void PlayReverse()
    {
        StopAllCoroutines();
        StartCoroutine(EndToStart());
    }

    IEnumerator StartToEnd()
    {
        float startTime;
        startTime = Time.time;

        float value_Y = 0;
        if (value_X!= 0)//如果一个tween还没结束就切换到反转的tween,相当于startTime提前
        {
            startTime = Time.time - (value_X * TimeClamp);
        }
        //协程循环
        while (value_X < 1)//直到到达X时间轴为1
        {
            value_X = (Time.time - startTime) / TimeClamp;
            value_Y = curveTest.Evaluate(value_X);

           if(tweenKind==Tweenkind.Transform)
            {
                this.transform.position = StartPoint + moveLength * value_Y;
            }
           else if(tweenKind == Tweenkind.RectTransform)
            {
                this.rectTransform.anchoredPosition = StartPoint + moveLength * value_Y;
            }

            yield return 0;
        }
        value_X =1;//大于1矫正

       // OnPlayComplete();
    }

    IEnumerator EndToStart()//如果一个tween还没结束就切换到反转的tween,相当于startTime提前
    {      
        float startTime;
        startTime = Time.time;

        float value_Y = 0;

        if(value_X!=1) 
        {
            startTime = Time.time - ((1 - value_X) * TimeClamp);
        }      
        //协程循环
        while (value_X>0)//直到到达X时间轴为0
        {
            value_X = 1- ((Time.time - startTime) / TimeClamp);
            value_Y = curveTest.Evaluate(value_X);

            if (tweenKind == Tweenkind.Transform)
            {
                this.transform.position = StartPoint + moveLength * value_Y;
            }
            else if (tweenKind == Tweenkind.RectTransform)
            {
                this.rectTransform.anchoredPosition = StartPoint + moveLength * value_Y;
            }

                yield return 0;
        }
        value_X =0; //小于0矫正
    }

//   public void OnPlayComplete()//播放完成调用
//   {
//        Time.timeScale = 0;
//    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值