因为制作的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;
// }
}