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

本文介绍了在Unity3D中实现简易DOTween的过程,包括作业要求、实现思路和具体实现步骤。作者通过研究DOTween官网,理解其运作模式,使用静态类封装脚本函数,利用getter和setter、委托以及协程实现Tween的动态管理和执行。文章还提供了代码结构和测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值