Unity3D从入门到放弃(七) ----DoTween的实现

来源:互联网 发布:淘宝新规则2016年9月 编辑:程序博客网 时间:2024/05/16 14:24

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);        }        static float CircBoth(float from, float to, float time)        {            return time < 0.5f ? CircIn(from, (from + to) / 2, time * 2) : CircOut((from + to) / 2, to, 2 * time - 1f);        }        // 弹性弧线        public static float ElasticIn(float from, float to, float time)        {            if (time == 0.0f) return from;            if (time == 1.0f) return to;            return from + (to - from) * -Mathf.Pow(2.0f, 10.0f * time - 10.0f) * Mathf.Sin((3.33f * time - 3.58f) * Mathf.PI * 2);        }        public static float ElasticOut(float from, float to, float time)        {            if (time == 0.0f) return from;            if (time == 1.0f) return to;            return from + (to - from) * (Mathf.Pow(2.0f, -10.0f * time) * Mathf.Sin((3.33f * time - 0.25f) * Mathf.PI * 2) + 1.0f);        }        public static float ElasticBoth(float from, float to, float time)        {            return time < 0.5f ? ElasticIn(from, (from + to) / 2, time * 2) : ElasticOut((from + to) / 2, to, 2 * time - 1f);        }        // back曲线        public static float BackIn(float from, float to, float time)        {            return from + (to - from) * time * time * (2.70158f * time - 1.70158f);        }        public static float BackOut(float from, float to, float time)        {            return from + (to - from) * (Mathf.Pow(time - 1, 2f) * (2.70158f * time - 1f) + 1.0f);        }        public static float BackBoth(float from, float to, float time)        {            return time < 0.5f ? BackIn(from, (from + to) / 2, time * 2) : BackOut((from + to) / 2, to, 2 * time - 1f);        }        // 弹性曲线        public static float BounceOut(float from, float to, float time)        {            if (time < 0.363636f) return from + (to - from) * 7.5625f * time * time;            else if (time < 0.72727f)            {                time -= 0.545454f;                return from + (to - from) * (7.5625f * time * time + 0.75f);            }            else if (time < 0.909091f)            {                time -= 0.818182f;                return from + (to - from) * (7.5625f * time * time + 0.9375f);            }            else            {                time -= 0.954545f;                return from + (to - from) * (7.5625f * time * time + 0.984375f);            }        }        public static float BounceIn(float from, float to, float time)        {            if (time > 0.636364f)            {                time = 1.0f - time;                return from + (to - from) * (1.0f - 7.5625f * time * time);            }            else if (time > 0.27273f)            {                time = 0.454546f - time;                return from + (to - from) * (0.25f - 7.5625f * time * time);            }            else if (time > 0.090909f)            {                time = 0.181818f - time;                return from + (to - from) * (0.0625f - 7.5625f * time * time);            }            else            {                time = 0.045455f - time;                return from + (to - from) * (0.015625f - 7.5625f * time * time);            }        }        public static float BounceBoth(float from, float to, float time)        {            return time < 0.5f ? BounceIn(from, (from + to) / 2, time * 2) : BounceOut((from + to) / 2, to, 2 * time - 1f);        }        #endregion    }}

ExpendClassFuntion:

/* * 描 述:用于各种控件,展示扩展函数,进行链式调用 * 作 者:hza  * 创建时间:2017/05/08 23:09:03 * 版 本:v 1.0 */using My.LerpFunctionSpace;using System.Collections;using System.Collections.Generic;using UnityEngine;namespace My.DoTween.Core{    public static class TweenClassFunction    {        // 设置前置函数        public static T OnStart<T>(this T tween, TweenCallBack _callfore) where T : Tween        {            tween.callfore = _callfore;            return tween;        }        // 设置回调函数        public static T OnComplete<T>(this T tween, TweenCallBack _callback) where T : Tween        {            tween.callback = _callback;            return tween;        }        // 设置循环次数,如果循环次数<=0,无限循环        public static T SetLoopTime<T>(this T tween, int looptime) where T : Tween        {            if (looptime < 0) looptime = 0;            tween.loopTime = looptime;            return tween;        }        // 暂停动作        public static T Pause<T>(this T tween) where T : Tween        {            tween.pause = true;            return tween;        }        // 停止动作        public static T Stop<T>(this T tween) where T : Tween        {            tween.stop = true;            return tween;        }    }    public static class TweenerClassFunction    {        // tweener        // 是否在队列内        public static bool isInQueue<T>(this T tweener) where T : Tweener        {            return tweener.isInqueue;        }        // 设置差值种类        public static T SetEaseType<T>(this T tweener, LerpFunctionType type) where T : Tweener        {            tweener.lerptype = type;            return tweener;        }    }    public static class SequenceClassFunction    {        // sequence        // 后面添加新节点        public static T Append<T>(this T sequence, Tweener tweener) where T : Sequence        {            MyDoTween.DeleteCoroutineAndTween(tweener);            tweener.isInqueue = true;            sequence.tweenActions.Add(tweener);            return sequence;        }        // 在后面添加新的回调函数        public static T AppendCallback<T>(this T sequence, TweenCallBack callback) where T : Sequence        {            sequence.tweenActions.Add(callback);            return sequence;        }        // 在后面添加新的等待时间        public static T AppendInterval<T>(this T sequence, float time) where T : Sequence        {            return sequence.Append(MyDoTween.To(() => time, x => time = x, 0, time));        }        // 前面添加新节点        public static T Prepend<T>(this T sequence, Tweener tweener) where T : Sequence        {            MyDoTween.DeleteCoroutineAndTween(tweener);            tweener.isInqueue = true;            sequence.tweenActions.Insert(0, tweener);            return sequence;        }        // 在前面添加新的回调函数        public static T PrependCallback<T>(this T sequence, TweenCallBack callback) where T : Sequence        {            sequence.tweenActions.Insert(0, callback);            return sequence;        }        // 在前面添加新的等待时间        public static T PrependInterval<T>(this T sequence, float time) where T : Sequence        {            return sequence.Prepend(MyDoTween.To(() => time, x => time = x, 0, time));        }        // 任意位置添加新节点        public static T Insert<T>(this T sequence, int atPos, Tweener tweener) where T : Sequence        {            if (atPos > 0 && atPos < sequence.tweenActions.Count)            {                MyDoTween.DeleteCoroutineAndTween(tweener);                tweener.isInqueue = true;                sequence.tweenActions.Insert(atPos, tweener);            }            return sequence;        }        // 任意位置添加新的回调函数        public static T InsertCallback<T>(this T sequence, int atPos, TweenCallBack callback) where T : Sequence        {            if (atPos > 0 && atPos < sequence.tweenActions.Count)                sequence.tweenActions.Insert(atPos, callback);            return sequence;        }    }    public static class TransformClassFunction    {        // transform        public static Tweener DOMove(this Transform transform, Vector3 to, float duration)        {            return MyDoTween.To(() => transform.position, x => transform.position = x, to, duration);        }        public static Tweener DOMoveX(this Transform transform, float to, float duration)        {            MyGetter<float> getter = () =>            {                return transform.position.x;            };            MySetter<float> setter = x =>            {                transform.position = new Vector3(x, transform.position.y, transform.position.z);            };            return MyDoTween.To(getter, setter, to, duration);        }        public static Tweener DOMoveY(this Transform transform, float to, float duration)        {            MyGetter<float> getter = () =>            {                return transform.position.y;            };            MySetter<float> setter = y =>            {                transform.position = new Vector3(transform.position.x, y, transform.position.z);            };            return MyDoTween.To(getter, setter, to, duration);        }        public static Tweener DOMoveZ(this Transform transform, float to, float duration)        {            MyGetter<float> getter = () =>            {                return transform.position.z;            };            MySetter<float> setter = z =>            {                transform.position = new Vector3(transform.position.x, transform.position.y, z);            };            return MyDoTween.To(getter, setter, to, duration);        }        public static Tweener DORotate(this Transform transform, Vector3 to, float duration)        {            return MyDoTween.To(() => transform.eulerAngles, x => transform.eulerAngles = x, to, duration);        }        public static Tweener DORotateQuaternion(this Transform transform, Quaternion to, float duration)        {            return MyDoTween.To(() => transform.rotation, x => transform.rotation = x, to, duration);        }        public static Tweener DOLocalRotate(this Transform transform, Vector3 to, float duration)        {            return MyDoTween.To(() => transform.localEulerAngles, x => transform.localEulerAngles = x, to, duration);        }        public static Tweener DOLocalRotateQuaternion(this Transform transform, Quaternion to, float duration)        {            return MyDoTween.To(() => transform.localRotation, x => transform.localRotation = x, to, duration);        }        public static Tweener DOScale(this Transform transform, Vector3 to, float duration)        {            return MyDoTween.To(() => transform.localScale, x => transform.localScale = x, to, duration);        }        public static Tweener DOScale(this Transform transform, float to, float duration)        {            return transform.DOScale(transform.localScale * to, duration);        }    }    public static class MaterialClassFunction    {        // material        public static Tweener DOColor(this Material material, Color to, float duration)        {            return MyDoTween.To(() => material.color, x => material.color = x, to, duration);        }    }}

MyTweenCore:(保存Tween类和他的子类)
其中关于in和out关键字可以点我

/* * 描 述:实现Tween,Tweener,Tweener<T>和Sequence类,用于实现基本动作类 * 作 者:hza  * 创建时间:2017/05/07 12:59:33 * 版 本:v 1.0 */using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using My.LerpFunctionSpace;using UnityEditor;namespace My.DoTween.Core{    // get模板委托    public delegate T MyGetter<out T>();    // set模板委托    public delegate void MySetter<in T>(T value);    // 回调委托    public delegate void TweenCallBack(Tween tween, object data);    /// <summary>    /// 一切动作的基类,扩展Tweener和Sequence    /// </summary>    public abstract class Tween     {        public object          id;            // Tween的标识,要进行动作的主体        public object          userData;      // 用户信息,用于回调函数        public bool            pause;         // 暂停        public bool            stop;          // 停止        public bool            isBegin;       //动作是否开始        public int             loopTime;      // 动作循环次数        public TweenCallBack   callfore;      // 前置函数        public TweenCallBack   callback;      // 回调函数        // 空构造函数        protected Tween() {}        public virtual void Clear()        {            id = null;            userData = null;            callfore = null;            callback = null;        }        // update函数模板        public abstract void Update(float dt);    }    /// <summary>    /// Tween的向上继承,保存各种函数,真正的动作基类    /// </summary>    public abstract class Tweener : Tween    {        public float            curTime;       // 当前时间        public float            duration;      // 动作持续时间        public LerpFunctionType lerptype;      // 插值种类        public bool             isInqueue;     // 是否在Sequence里面         public abstract Tweener From();    }    /// <summary>    /// 模板类,用于储存各种模板事件    /// </summary>    /// <typeparam name="T"></typeparam>    public class Tweener<T> : Tweener    {        public MyGetter<T>       getter;        // 起始位置的getter        public MySetter<T>       setter;        // 起始位置的setter        public T                 begValue;      // 起始位置         public T                 endValue;      // 目标位置        public ChangeValue       change;        // 改变T的值        // time范围为0-1        public delegate T ChangeValue(T from, T to, float time);        // 构造函数        public static Tweener<T> Create(MyGetter<T> getter, MySetter<T> setter, T endValue, float duration) {            Tweener<T> tweener = new Tweener<T>();            // Tween            tweener.id           = MyDoTween.GetUniqueTweenerID();            tweener.userData     = getter();            tweener.pause        = false;            tweener.stop         = false;            tweener.isBegin      = false;            tweener.loopTime     = 1;            tweener.callfore     = null;            tweener.callback     = null;            // Tweener            tweener.duration     = duration;            tweener.isInqueue    = false;            tweener.curTime      = 0;            tweener.lerptype     = 0;            // tweener<T>            tweener.getter       = getter;            tweener.setter       = setter;            tweener.begValue     = getter();            tweener.endValue     = endValue;            return tweener;        }        // 使动作反转        public override Tweener From()        {            // from仅仅建立在动作未开始时            if (!isBegin)            {                // 目标互换                setter(endValue);                endValue = begValue;                begValue = getter();            }            return this;        }        public override void Update(float dt)        {            // 表示动作开始            if (!isBegin)            {                if (callfore != null) callfore(this, userData);                // 更新物体位置                begValue = getter();                isBegin = true;            }            if (curTime < duration) {                if (curTime + dt >= duration)                {                    // 如果达到目标值,设置最终地点                    setter(endValue);                    if (--loopTime == 0)                    {                        if (callback != null) callback(this, userData);                        stop = true;                    }                    else                    {                        curTime = 0;                        setter(begValue);                    }                    return;                }                // 设置属性值                setter(change(begValue, endValue, curTime / duration));                // 增加时间                curTime += dt;            }        }    }    /// <summary>    /// 序列类,用于动作的连续进行    /// </summary>    public class Sequence : Tween    {        public List<object> tweenActions;  // 动作,函数队列        public int currentObjectIndex;  // 当前动作位置        public object currentObject;  // 当前动作,或函数        // 空构造函数        public static Sequence create()        {            Sequence sequence = new Sequence();            sequence.id                 = MyDoTween.GetUniqueSequenceID();            sequence.userData           = null;            sequence.pause              = false;            sequence.stop               = false;            sequence.isBegin            = false;            sequence.loopTime           = 1;            sequence.callfore           = null;            sequence.callback           = null;            sequence.tweenActions       = new List<object>();            sequence.currentObjectIndex = 0;            sequence.currentObject      = null;            return sequence;        }        public override void Clear()        {            // 基类调用            base.Clear();            // 清除列表内的Tween            foreach (object tween in tweenActions)                if (tween is Tween) ((Tween)tween).Clear();        }        public override void Update(float dt)        {            // 表示动作开始            if (!isBegin)            {                if (callfore != null) callfore(this, userData);                isBegin = true;            }            // 如果暂停,返回            if (pause) return;            // 在列表内            if (currentObjectIndex >= 0 && currentObjectIndex < tweenActions.Count)            {                // 设置当前Object                if (currentObject == null) currentObject = tweenActions[currentObjectIndex];                // 判断Object种类                if (currentObject is Tween)                {                    Tweener currentAction = (Tweener)currentObject;                    // 动作完成                    if (currentAction.stop)                    {                        currentObject = null;                        currentObjectIndex++;                        return;                    }                    // 动作暂停                    if (currentAction.pause) return;                    // 执行动作                    currentAction.Update(dt);                }                else                {                    TweenCallBack callback = (TweenCallBack)currentObject;                    currentObject = null;                    currentObjectIndex++;                    callback(this, this.userData);                }            }            // 动作执行完成            else if (currentObjectIndex >= tweenActions.Count)            {                if (--loopTime == 0)                {                    if (callback != null) callback(this, userData);                    stop = true;                }                else                {                    foreach (Tweener tweener in tweenActions)                    {                        tweener.stop = false;                        tweener.curTime = 0;                    }                    currentObjectIndex = 0;                }            }        }    }}

MyDoTween:

/* * 描 述:实现DoTween静态类 * 作 者:hza  * 创建时间:2017/05/07 24:29:03 * 版 本:v 1.0 */using System.Collections;using System.Collections.Generic;using UnityEngine;using My.LerpFunctionSpace;using My.DoTween.Core;using System;namespace My.DoTween {    public static class MyDoTween    {        // 自动执行        public static bool StartAuto = true;        private static bool isBegin = false;        // tweener容量        public static int TweenerMaxSize = 100;        // sequence容量        public static int SequenceMaxSize = 30;        public static void Init(bool startAuto, int tweenerSize = 100, int sequenceSize = 30)        {            // 如果未启动,修改变量            if (!isBegin)            {                StartAuto = startAuto;                TweenerMaxSize = tweenerSize;                SequenceMaxSize = sequenceSize;            }        }        // 创建新Sequence        public static Sequence Sequence()        {            Sequence se = My.DoTween.Core.Sequence.create();            AddCoroutineAndTween(se);            return se;        }        public static object GetUniqueTweenerID()        {            // 当新建Tween时,不允许修改条件            isBegin = true;            if (TweenerMaxSize == 0)                throw new KeyNotFoundException("Tween超出数量限制");            TweenerMaxSize--;            return "Tweener" + Guid.NewGuid();        }        public static Tween FreeTweener(Tween tween)        {            tween.Clear();            tween = null;            TweenerMaxSize++;            return tween;        }        public static object GetUniqueSequenceID()        {            // 当新建Tween时,不允许修改条件            isBegin = true;            if (SequenceMaxSize == 0)                throw new KeyNotFoundException("Sequence超出数量限制");            SequenceMaxSize--;            return "Sequence" + Guid.NewGuid();        }        public static Tween FreeSequence(Tween tween)        {            tween.Clear();            tween = null;            SequenceMaxSize++;            return tween;        }        #region To重载        public static Tweener To(MyGetter<float> getter, MySetter<float> setter, float endValue, float duration)        {            // 设置属性            Tweener<float> newTweener = Tweener<float>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return LerpFunction.lerfs[(int)newTweener.lerptype](from, to, time);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<double> getter, MySetter<double> setter, double endValue, float duration)        {            // 设置属性            Tweener<double> newTweener = Tweener<double>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return from + (to - from) * LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<int> getter, MySetter<int> setter, int endValue, float duration)        {            // 设置属性            Tweener<int> newTweener = Tweener<int>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                // 四舍五入                return from + (int)((to - from) * LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time) + 0.5);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Vector2> getter, MySetter<Vector2> setter, Vector2 endValue, float duration)        {            // 设置属性            Tweener<Vector2> newTweener = Tweener<Vector2>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return from + (to - from) * LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Vector3> getter, MySetter<Vector3> setter, Vector3 endValue, float duration)        {            // 设置属性            Tweener<Vector3> newTweener = Tweener<Vector3>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return from + (to - from) * LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Vector4> getter, MySetter<Vector4> setter, Vector4 endValue, float duration)        {            // 设置属性            Tweener<Vector4> newTweener = Tweener<Vector4>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return from + (to - from) * LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time);            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Quaternion> getter, MySetter<Quaternion> setter, Quaternion endValue, float duration)        {            // 设置属性            Tweener<Quaternion> newTweener = Tweener<Quaternion>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return Quaternion.Lerp(from, to, LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time));            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Rect> getter, MySetter<Rect> setter, Rect endValue, float duration)        {            // 设置属性            Tweener<Rect> newTweener = Tweener<Rect>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return new Rect(LerpFunction.lerfs[(int)newTweener.lerptype](from.x, to.x, time),                                LerpFunction.lerfs[(int)newTweener.lerptype](from.y, to.y, time),                                LerpFunction.lerfs[(int)newTweener.lerptype](from.width, to.width, time),                                LerpFunction.lerfs[(int)newTweener.lerptype](from.height, to.height, time));            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<RectOffset> getter, MySetter<RectOffset> setter, RectOffset endValue, float duration)        {            // 设置属性            Tweener<RectOffset> newTweener = Tweener<RectOffset>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return new RectOffset((int)LerpFunction.lerfs[(int)newTweener.lerptype](from.left, to.left, time),                                      (int)LerpFunction.lerfs[(int)newTweener.lerptype](from.right, to.right, time),                                      (int)LerpFunction.lerfs[(int)newTweener.lerptype](from.top, to.top, time),                                      (int)LerpFunction.lerfs[(int)newTweener.lerptype](from.bottom, to.bottom, time));            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        public static Tweener To(MyGetter<Color> getter, MySetter<Color> setter, Color endValue, float duration)        {            Tweener<Color> newTweener = Tweener<Color>.Create(getter, setter, endValue, duration);            newTweener.change = (from, to, time) =>            {                return Color.Lerp(from, to, LerpFunction.lerfs[(int)newTweener.lerptype](0, 1, time));            };            // 加入Tween            AddCoroutineAndTween(newTweener);            return newTweener;        }        #endregion        #region 调用Manager类函数        public static void AddCoroutineAndTween(Tween tween)        {            MyTweenManager manager = MyTweenManager.GetInstance();            manager.AddCoroutineAndTween(tween);        }        public static void DeleteCoroutineAndTween(Tween tween)        {            MyTweenManager manager = MyTweenManager.GetInstance();            manager.DeleteCoroutineAndTween(tween);        }        public static List<Tween> GetAllTween()        {            MyTweenManager manager = MyTweenManager.GetInstance();            return manager.GetAllTween();        }        public static List<Tween> GetAllPauseTween()        {            MyTweenManager manager = MyTweenManager.GetInstance();            return manager.GetAllPauseTween();        }        public static List<Tween> GetAllPlayingTween()        {            MyTweenManager manager = MyTweenManager.GetInstance();            return manager.GetAllPlayingTween();        }        #endregion    }}

MyTweenManager:(继承MonoBehaviour,调用协程)
关于协程部分可以点我

/* * 描 述:实现DoTweenManager类,用于挂在在脚本上并调用协程 * 作 者:hza  * 创建时间:2017/05/07 21:25:03 * 版 本:v 1.0 */using My.DoTween;using My.DoTween.Core;using System;using System.Collections;using System.Collections.Generic;using UnityEngine;// Pair数据结构public class Pair<T1, T2>{    public T1 first;    public T2 second;    public Pair(T1 first, T2 second) {        this.first = first;        this.second = second;    }} public class MyTweenManager : MonoBehaviour {    private static MyTweenManager _instance;    public static MyTweenManager GetInstance()    {        if (_instance == null)        {            // 要使用时,创建新空物体并把脚本挂载在上面            GameObject gameobject = new GameObject("[MyToTweenManager]");            gameobject.AddComponent<MyTweenManager>();            _instance = gameobject.GetComponent<MyTweenManager>();        }        return _instance;    }    // 储存正在进行的tween和对应的协程的Pair,Key值为Tween的id属性    private static Dictionary<object, Pair<Tween, Coroutine>> tweenDictionary = new Dictionary<object, Pair<Tween, Coroutine>>();    // 加入新Tween,并创建线程    public void AddCoroutineAndTween(Tween tween)    {        if (tweenDictionary.ContainsKey(tween.id) || tween.id == null)            throw new InvalidCastException("该动作已经在进行");        // 如果设置自动播放,则立刻播放        tween.pause = !MyDoTween.StartAuto;        // 加入Tween        tweenDictionary.Add(tween.id, new Pair<Tween, Coroutine>(tween, StartCoroutine(ExcitingProgramming.Todo(this, tween))));    }    //删除Tween,并停止线程    public void DeleteCoroutineAndTween(Tween tween)    {        if (!tweenDictionary.ContainsKey(tween.id))            throw new KeyNotFoundException("不存在该动作!");        // 停止线程        StopCoroutine(tweenDictionary[tween.id].second);        // 删除该tween        tweenDictionary.Remove(tween.id);    }    // 寻找字典中所有的Tween    public List<Tween> GetAllTween()    {        List<Tween> tweenList = new List<Tween>();        foreach (KeyValuePair<object, Pair<Tween, Coroutine>> pair in tweenDictionary)            tweenList.Add(pair.Value.first);        return tweenList;    }    // 寻找字典中暂停的Tween    public List<Tween> GetAllPauseTween()    {        List<Tween> tweenList = new List<Tween>();        foreach (KeyValuePair<object, Pair<Tween, Coroutine>> pair in tweenDictionary)            if (!pair.Value.first.stop && pair.Value.first.pause) tweenList.Add(pair.Value.first);        return tweenList;    }    // 寻找字典中正在播放的Tween    public List<Tween> GetAllPlayingTween()    {        List<Tween> tweenList = new List<Tween>();        foreach (KeyValuePair<object, Pair<Tween, Coroutine>> pair in tweenDictionary)            if (!pair.Value.first.stop && !pair.Value.first.pause) tweenList.Add(pair.Value.first);        return tweenList;    }}// 协程的参数函数public static class ExcitingProgramming{    public static IEnumerator Todo(MyTweenManager manager, Tween tween)    {        // 从下一帧开始        yield return null;         // 判断是否stop        while (!tween.stop)        {            if (tween.pause)            {                yield return null;                continue;            }            tween.Update(Time.deltaTime);            yield return null;        }        // 清除tween        manager.DeleteCoroutineAndTween(tween);        // 删除tween        if (tween is Tweener) MyDoTween.FreeTweener(tween);        else MyDoTween.FreeSequence(tween);    }}

test3:(测试代码)

using System.Collections;using System.Collections.Generic;using UnityEngine;using My.DoTween;using My.DoTween.Core;public class test3 : MonoBehaviour {    // Use this for initialization    void Start () {        Tween tween = transform.DORotate(new Vector3(0, 0, 360), 2.5f).SetLoopTime(-1);        transform.DOMoveY(10, 5).SetEaseType(My.LerpFunctionSpace.LerpFunctionType.SineBoth);        Sequence se2 = MyDoTween.Sequence();        se2.Append(transform.DOMoveX(5, 2.5f).SetEaseType(My.LerpFunctionSpace.LerpFunctionType.SineOut))            .Append(transform.DOMoveX(0, 2.5f).SetEaseType(My.LerpFunctionSpace.LerpFunctionType.SineIn))            .AppendInterval(1f)            .AppendCallback((t, u) =>            {                tween.Stop();                transform.DOScale(3, 1);                transform.DOMoveY(0, 1.5f).SetEaseType(My.LerpFunctionSpace.LerpFunctionType.BounceOut);            });    }    // Update is called once per frame    void Update () {    }}

测试了一下,结果如下(还是可以实现各种动作的):
这里写图片描述


总结:

感觉类的关系还是有些搞不清啊,写的特慢,改来改去。什么时候能改掉这个大毛病呢= =

0 0