Unity3D从入门到放弃(七)
—-DoTween的实现
5.11修改:在Sequence里面新加入了Clear函数,目的是清除Sequence里List中的Tween。
作业要求:
请研究 DOTween 网站 http://dotween.demigiant.com/getstarted.php 网页, 它在 Specific settings 中 transform.DoMove 返回 Tween 对象。请实现该对象,实现对动作的持续管理。
本次作业要求完成DOTween实现的内容,DOTween网站已经放在上面。下面简介实现思路和具体实现。
实现思路:
观察了网站的DOTween运作并自己操作了一下,我猜测DOTween的运作模式为:创建一个空物体挂在的脚本,然后在该脚本上进行Tweener和Sequence的操作,并对他们进行管理和操作,而静态类DOTween对该脚本的函数进行封装,供用户使用。
(新建Tween出现的脚本)
(脚本信息)
Tween的另一个问题是如何修改函数的值,经过查资料,我了解了Tween的To函数通过getter和setter函数实时改变相应的值,因此我新加入了一个委托change,用于通过时间和插值函数,计算相应的中间值。
Tween第三个问题是如何执行,用Coroutine(协程)可以轻松解决这个问题,协程在每一帧自动从yield重新开始,可以代替Update。
根据这三个信息,可以构造简易DOTween了。
具体实现:
1.类结构如下
(其中ExtendClassFunction文件,包含各种静态类,每个静态类包含相应类的扩展函数)
2.代码如下
代码我会贴在下面,也可以从GitHub上下载,链接:我是下载传送门
LerpFunction:(插值函数类,半搬运半修改)
/*
* 描 述:存放各种插值函数的类
* 作 者:hza
* 创建时间:2017/05/07 00:48:02
* 版 本:v 1.0
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace My.LerpFunctionSpace
{
// Lerp函数类型
public enum LerpFunctionType : int
{
Linear = 0,
QuadIn = 1,
QuadOut = 2,
QuadBoth = 3,
CubicIn = 4,
CubicOut = 5,
CubicBoth = 6,
QuintIn = 7,
QuintOut = 8,
QuintBoth = 9,
SineIn = 10,
SineOut = 11,
SineBoth = 12,
ExpoIn = 13,
ExpoOut = 14,
ExpoBoth = 15,
CircIn = 16,
CircOut = 17,
CircBoth = 18,
ElasticIn = 19,
ElasticOut = 20,
ElasticBoth = 21,
BackIn = 22,
BackOut = 23,
BackBoth = 24,
BounceIn = 25,
BounceOut = 26,
BounceBoth = 27
}
/// <summary>
/// 用来进行各种线性插值的计算,time必须在0-1之间
/// </summary>
public static class LerpFunction
{
#region 委托和事件数组
public delegate float LFunction(float from, float to, float time);
public static LFunction[] lerfs = new LFunction[]
{
Linear,
QuadIn,
QuadOut,
QuadBoth,
CubicIn,
CubicOut,
CubicBoth,
QuintIn,
QuintOut,
QuintBoth,
SineIn,
SineOut,
SineBoth,
ExpoIn,
ExpoOut,
ExpoBoth,
CircIn,
CircOut,
CircBoth,
ElasticIn,
ElasticOut,
ElasticBoth,
BackIn,
BackOut,
BackBoth,
BounceIn,
BounceOut,
BounceBoth
};
#endregion
#region 私有Lerp函数
// 线性
public static float Linear(float from, float to, float time)
{
return from + (to - from) * time;
}
// 2次方程
public static float QuadIn(float from, float to, float time)
{
return from + (to - from) * time * time;
}
public static float QuadOut(float from, float to, float time)
{
return from + (to - from) * time * (2f - time);
}
public static float QuadBoth(float from, float to, float time)
{
return time < 0.5f ? QuadIn(from, (from + to) / 2, time * 2) : QuadOut((from + to) / 2, to, 2 * time - 1f);
}
// 3次方程
public static float CubicIn(float from, float to, float time)
{
return from + (to - from) * Mathf.Pow(time, 3f);
}
public static float CubicOut(float from, float to, float time)
{
return from + (to - from) * (Mathf.Pow(time - 1, 3f) + 1.0f);
}
public static float CubicBoth(float from, float to, float time)
{
return time < 0.5f ? CubicIn(from, (from + to) / 2, time * 2) : CubicOut((from + to) / 2, to, 2 * time - 1f);
}
// 5次方程
public static float QuintIn(float from, float to, float time)
{
return from + (to - from) * Mathf.Pow(time, 5f);
}
public static float QuintOut(float from, float to, float time)
{
return from + (to - from) * (Mathf.Pow(time - 1, 5f) + 1.0f);
}
public static float QuintBoth(float from, float to, float time)
{
return time < 0.5f ? QuintIn(from, (from + to) / 2, time * 2) : QuintOut((from + to) / 2, to, 2 * time - 1f);
}
// 正弦曲线
public static float SineIn(float from, float to, float time)
{
return from + (to - from) * (1.0f - Mathf.Cos(time * Mathf.PI / 2));
}
public static float SineOut(float from, float to, float time)
{
return from + (to - from) * Mathf.Sin(time * Mathf.PI / 2);
}
public static float SineBoth(float from, float to, float time)
{
return time < 0.5f ? SineIn(from, (from + to) / 2, time * 2) : SineOut((from + to) / 2, to, 2 * time - 1f);
}
// 指数增长
public static float ExpoIn(float from, float to, float time)
{
return time == 0.0f ? from : from + (to - from) * Mathf.Pow(2f, 10f * (time - 1f));
}
public static float ExpoOut(float from, float to, float time)
{
return time == 1.0f ? to : from + (to - from) * (1f - Mathf.Pow(2f, -10f * time));
}
public static float ExpoBoth(float from, float to, float time)
{
return time < 0.5f ? ExpoIn(from, (from + to) / 2, time * 2) : ExpoOut((from + to) / 2, to, 2 * time - 1f);
}
// 圆周弧线
static float CircIn(float from, float to, float time)
{
return from + (to - from) * (1.0f - Mathf.Sqrt(1f - time * time));
}
static float CircOut(float from, float to, float time)
{
return from + (to - from) * Mathf.Sqrt((2f - time) * time);