学习目标:

今天来介绍一下Unity的一个好插件DOTween,也就当复习巩固了,没想到在B站上看到了一个远古视频有老师教学怎么使用DOTween,于是在学习了42P视频后就讲学到的常用函数属性给大伙看一遍。

如果你想系统性的学习请看:Unity常用插件之DoTween_哔哩哔哩_bilibili详细了讲解了Unity中的常用插件DoTween的使用方法。icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Fx411Z7Bi?spm_id_from=333.851.header_right.fav_list.click

如果有懂哥的话肯定知道这个插件大致就是通过代码控制住动画,让游戏运行的时候能进行相应的动画,下列是公司说的优点

然后我们在Asset Store下载一个免费版的,然后倒入到Unity中

右下角Import一下,

导入成功后就会看到这个绿色按钮点一下等一会Apply成功后即可退出,DOTween插件成功导入。然后我们还可以在代码中引用它的命名空间了。

准备好了话就先创建一个3D 的项目,然后开始每个方法都要实践吧。

学习内容:

  红色注意:要使用它的命名空间要在一开始的using下添加命名空间using DG.Tweening;

 除非特殊说明,不然所有代码都是在Untiy自带的Start()函数上完成的。

  一:首先从移动和旋转,大小开始

 //transform.DOMove(Vet3目标点,float时长)
        //transform.DOMove(Vector3.one, 2f);
        //transform.DOMoveX() //移动x轴
        //transform.DOLocalMove() Unity中有自身坐标(相对)以及世界坐标(绝对)

还有另一种Punch的可以让你的移动反复(一般震动和弹性都是用默认的)

//DOPunchPosition反复开始和结尾的位置
        //transform.DOPunchPosition(new Vector3(0, 1, 0),2f,3,0.1f); //Vet3 时间 震动 弹性
//DORotate(Vet3目标度数,float时长)
        //transform.DORotate(new Vector3(50, 50, 50), 2f);
//DOScale(Vet3目标大小,float时长)
        //transform.DOScale(new Vector3(2, 2, 2), 2f);

然后还有一个震动的

 //震动的时长,强度,频率,随机的角度
        //transform.DOShakePosition(2f, 4, 10, 90);

二丶材质部分

  我们还可以用于修改材质

  首先创建一个3D Object 叫Cube,然后创建一个Material,再将照片给它

 可以见到我们两种Shader都用的不一样的

 如果我们用Patricals的,则啊草图片是显示不出来的。

下面是Standard

扯的有点远了,首先我们用回第一张图的Shader,然后我们开始介绍代码

//材质
        Material material = GetComponent<MeshRenderer>().material;
        //DOColor(Color你想要改变的颜色,把颜色赋值给Shader属性的Color(默认"_Color",看你用的是什么shader了),时长)
        //material.DOColor(Color.red,"_TintColor", 2);

 那么这个_TintColor在哪里看呢?就在你的材质里,找到Color的名字后复制粘贴进去,不然会报错的(Standard则没有这种问题)点击Edit,可以看到它的属性

//修改透明度第一方法:DOColor()将颜色清零
        //material.DOColor(Color.clear, "_TintColor", 2f);

 //修改透明度第二方法:DOFade(Float Fade你想要改变的透明度大小,把颜色赋值给Shader属性的Color(默认"_Color",看你用的是什么shader了),时长)
        //material.DOFade(0, "_TintColor", 2f);

如果要修改颜色的渐变值,首先我们要在回调函数外声明一个Grandient类

public Gradient gradient;//渐变

//渐变颜色DOGradientColor(Gradient 要渐变的,指定的属性, float时长)
        //material.DOGradientColor(gradient, "_TintColor", 2);

材料的纹理坐标指的是Offset

 可以改变它的Offset让Material有个滚动的效果

//纹理偏移值DOOffset(Vec2 Offset,float 时长)
        //material.DOOffset(new Vector2(1, 1), 2);

我们还有一个混合模式,如果你只是单纯的列两条函数,那它只会执行后一条

//这两行最终执行结果也只是变为绿色
        //material.DOColor(Color.red,"_TintColor", 2);
        //material.DOColor(Color.green, "_TintColor", 2);

但你用了混合模式就不一样了,它会选择两种颜色的中间色

//材质的混合模式
        material.DOBlendableColor(Color.red, "_TintColor", 2);
        material.DOBlendableColor(Color.green, "_TintColor", 2);

三丶摄像机属性相关的动画

再声明一遍,如果你想要使用这些扩展函数的话,一定要引用命名空间using DG.Tweening;

首先我们创建一个脚本挂载到摄像机上,再获取Camera组件,

Camera cam = GetComponent<Camera>();

//设置摄像机宽高比cam.DOAspect(float 宽高比值,float 时长)
        //cam.DOAspect(1.5f, 2);

//设置摄像机的背景颜色(Color 你要变换的颜色,float 时长)
        //cam.DOColor(Color.red, 2f);

//设置摄像机的近切面和远切面(Clipping Plane)Near,Far
        //cam.DONearClipPlane(1.4f, 2f);
        //cam.DOFarClipPlane(5f, 2f);

点开摄像机其实是这里

//设置Perspective摄像机的视域Fiew of View
        //DOFieldOfView(float size,float 时长)
        //cam.DOFieldOfView(100f, 2f);
        //cam.DOOrthoSize()调整正交摄像机otherographic的视域大小
        //cam.DOOrthoSize(6f, 2f);

这里涉及到摄像机的两种透视模式

//设置摄像机在屏幕的比例cam.DORect(Rect 矩形,float时长)
        //cam.DORect(new Rect(0, 0, 0.5f, 0.5f),2f);
 //根据像素设置摄像机在屏幕的比例
        cam.DOPixelRect(new Rect(0, 0, 512, 384), 2f);

这里则是摄像机能在屏幕上显示的比例(一种是多少比例,一种是多少个像素)

 我用的是1024:768个像素比

 设置摄像机抖动这个是最常见的:

//设置相机的震动(float时长,float 强度,int 频率,float 随机度数)
        cam.DOShakePosition(2);

四丶UI部分

可以看到这个DOTween真的已经覆盖了Unity组件的大部分。

首先是Text我们可以让Text像打字机一样输出文字,后面的SetEase()函数表示我们可以使用什么类型的模式来输出,每一种大伙都可以试一下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class TextDOTween : MonoBehaviour
{
    
    void Start()
    {
        Text text = GetComponent<Text>();
        //text.DOText(string,float).SetEase(样式)
        text.DOText("abcdefghijklmnopqrstuvwxyz", 5f).SetEase(Ease.Linear);
    }

   
}

同样,我们也可以用在Button上

这里简单写一点了,比如直接创建一个脚本然后挂载在一个新建的Button上,当触发点击事件的时候回进行反复移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class ButtonDOTween : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void aniBtn()
    {
        transform.DOPunchPosition(new Vector3(0, 20, 0), 0.4f,6,0.3f);
        transform.DOPunchScale(new Vector3(0.3f, 0, 0), 0.3f, 4, 0.4f);
    }
}

截的不是很好,但可以看出按钮已经播放动画了。

 五丶(核心部分)运动序列

  之所以我称呼他为核心部分,是因为它可以为某个动画添加各种一样行为,顺序逆序

首先我们先创建一个运动队列

运动队列本身就是一个队列,它所创建的所有序列都遵循队列的先进先出的顺序

Sequence sequence = DOTween.Sequence();
 sequence.Append(transform.DOMove(Vector3.one, 2f));//0-2
        //在上一个动作的基础上再加一个动作Join(Tween 动作)

//插入在某一时刻插入某个动作Insert(flaot 时刻,Tween 动作)
        //sequence.Insert(0, transform.DOMove(-Vector3.one, 1.5f)); //从第0秒开始,就把一开始的Apeend给替换掉了

sequence.InsertCallback(2, appCallBack); 
 
private void appCallBack()
    {
        Debug.Log("InsertCallBack");

    }
 sequence.Join(transform.DOScale(Vector3.one * 2, 2f));
 //下列这两步和上面的Join一样
        //sequence.Insert(0f, transform.DOScale(Vector3.one * 2, 2f));
        //sequence.Insert(3f, transform.DOScale(Vector3.one, 2f));
 //sequence.AppendCallback(); 回调函数
 //我们现在Start()外面创建一个函数
 private void appendCallBack()
    {
        Debug.Log("AppendCallBack");
    }
  然后就可以调用它了
  sequence.AppendCallback(appendCallBack);

接下来介绍反过来的添加动作Prepend预添加Prepend则是一个栈 后进先出的

执行的顺序是先执行Prepend,再执行Append

 sequence.PrependInterval(1f); //等待一秒
        sequence.Prepend(transform.DOMove(-Vector3.one, 2f)); //先反方向
        sequence.PrependCallback(prependCallBack);



  private void prependCallBack()
    {
        Debug.Log("PrependCallBack");
    }

这些是先执行的。

六丶运动参数TweenParams

  也是挺重要的,标记为紫色。

  首先要创建一个对象

TweenParams tp = new TweenParams();

然后是设置循环,第一个参数是循环的次数(如果是-1则代表无限循环,后面是循环的类型有Yoyo,Restart等)

 TweenParams tp = new TweenParams();
        //tp.SetLoops(-1, LoopType.Yoyo);

给一个动作赋予参数(通常bool值为false)

 //transform.DOMove((Vector3.one), 1f).SetAs(tp).SetAutoKill(); //SetAutoKill()动作完成时自动销毁
        //transform.DOMove((Vector3.one), 1f).From(true); //From(bool 基于方向进行移动,如果两个点重合的话,如果设置为true 即使两个点重合还会根据方向移动过来,如果都是(1,1,1)),他会从
//设置延迟参数
        //transform.DOMove(Vector3.one, 1).SetDelay(3f);
        //设置速度(DOMove里面的数字10就是速度)
        //transform.DOMove(Vector3.one, 10).SetSpeedBased(true); //SetSpeedBased(bool true则是速度,false则是时间)

 通过ID来编号你要执行的动作

//设置 SetId(string ID名字)
        //transform.DOMove(Vector3.one, 2f).SetId("ID03");
        //DOTween.Play("ID03");
//设置可回收的
        //transform.DOMove(Vector3.one, 2f).SetRecyclable();

        //设置增量的使用
        //transform.DOMove(Vector3.one, 2f).SetRelative();
//SetUpdate(UpdateType Upadte的类型Normal则是通常的,bool 播放的时间帧值true则不受Time.scaletime控制)
        //transform.DOMove(Vector3.one, 2f).SetUpdate(UpdateType.Normal,true);
//Linear匀速 Flash闪动 float 10速度的变换 
        //transform.DOMove(Vector3.one, 2f).SetEase(Ease.Linear,10,0);

自定义曲线,首先要在开头声明一个

public AnimationCurve ac;

可以看到在Inspector面板上我们点击后可以选择你的曲线,也可以通过鼠标右键点击Add Key来添加属性让曲线呈现你想要的。

//自定义曲线Easer、
        //transform.DOMove(Vector3.one, 2).SetEase(ac);

你也可以自定义一个函数来绘制曲线

 //自定义函数型曲线
        //transform.DOMove(Vector3.one, 2).SetEase(MyEaseRun);

private float MyEaseRun(float time, float duration, float overshootOrAmplitude, float period)
    {
        return time / duration;
    }

八丶回调函数

  DOTween上的回调函数同样也是非常重要的内容。

 例如我们可以用Lamada表达式来创造动作完成时候的回调

//Lamada表达式OnComplete
        //transform.DOMove(Vector3.one, 2f).OnComplete(() => { Debug.Log("kkjjj"); });

除此之外还有其他的,与Unity的MonoBehavior自带的回调函数相似知识在前面加了个on

还有一个输出动作的时间点fullPosition这里以异步为例

接下来介绍fullPosition,这里引用异步函数,首先先声明两个命名空间

using System;
using System.Threading.Tasks;

async void Start()
    {
       

        var tweener = transform.DOMove(Vector3.one, 2f);
        await Task.Delay(TimeSpan.FromSeconds(1));
        //tweener.fullPosition = 2; //如果是2,则表示暂停线程1秒后直接到达2秒的位置
        Debug.Log(tweener.fullPosition); //返回的是当前位置是在总时间的第几秒
        //动画的时间时刻tweener.fullPosition;
}

可以看到它通过当前位置计算出方块的位置相当于总时间的多少秒

等我们把注释解掉,仅有一秒就运行到本来动画2秒就要运行到的位置


//var tweener = transform.DOMove(Vector3.one, 1f).SetLoops(3);
        //获取有多少个暂停动画tweener.Delay();

        //执行的时间tweener.Duration(bool 是否包含循环) false则是总时长(1),true则要乘以循环次数(1*3);

        //已经执行完成的时间tweener.Elapsed(bool 是否包含循环) false则是总时长(1),true则要乘以循环次数(1 * 3));

        //动画的播放进度[0,1]tweener.ElapsedDirectionalPercentage()

        //tweener.ElapsedPercentage(bool); //也有判断是否包含循环
//可以看是否包括循环,如果是则返回整体循环的百分比  tweener.ElapsedPercentage(bool);
        //返回循环次数tweener.Loops();

        //await Task.Delay(TimeSpan.FromSeconds(1));
        //Debug.Log(tweener.CompletedLoops());
        //await Task.Delay(TimeSpan.FromSeconds(1));
        //Debug.Log(tweener.CompletedLoops());
        //await Task.Delay(TimeSpan.FromSeconds(1));
        //Debug.Log(tweener.CompletedLoops());
//transform.DORestart();
        //transform.DORewind(); //重新回到开始位置
        //transform.DOSmoothRewind();// 平滑的重新回到开始位置
        //transform.DOPause(); //暂停
        //transform.DOPlay(); //播放
        //transform.DORestart(); //重新开始

        //await Task.Delay(TimeSpan.FromSeconds(1)); //延迟人物,把秒转化为毫秒TimeSpan.FromSeconds
        //transform.DORewind(); //回到开始的位置
        //transform.DOSmoothRewind();

        //transform.DOFlip();
        //transform.DOGoto(1,true); //float跳到那个时间点,bool 是否继续播放
        //transform.DOPlayForward();
        //transform.DOPlayBackwards();
        //transform.DOTogglePause(); //暂停一瞬间感觉没什么用
        //await Task.Delay(TimeSpan.FromSeconds(1));
        //transform.DOTogglePause();

九丶类方法

  用于统筹你的之前创造的动画动作等。

//transform.DORestart();
        //transform.DORewind(); //重新回到开始位置
        //transform.DOSmoothRewind();// 平滑的重新回到开始位置
        //transform.DOPause(); //暂停
        //transform.DOPlay(); //播放
        //transform.DORestart(); //重新开始

        //await Task.Delay(TimeSpan.FromSeconds(1)); //延迟人物,把秒转化为毫秒TimeSpan.FromSeconds
        //transform.DORewind(); //回到开始的位置
        //transform.DOSmoothRewind();

        //transform.DOFlip();
        //transform.DOGoto(1,true); //float跳到那个时间点,bool 是否继续播放
        //transform.DOPlayForward();
        //transform.DOPlayBackwards();
        //transform.DOTogglePause(); //暂停一瞬间感觉没什么用
        //await Task.Delay(TimeSpan.FromSeconds(1));
        //transform.DOTogglePause();

十丶协程

  协程与进程不同,一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。(引用文章:unity 协程原理与线程的区别_天涯过客TYGK的博客-CSDN博客_协程与线程的区别icon-default.png?t=N7T8https://blog.csdn.net/u011484013/article/details/51136780?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165209865816782246448450%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165209865816782246448450&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-51136780-null-null.142%5Ev9%5Econtrol,157%5Ev4%5Econtrol&utm_term=unity%E5%8D%8F%E7%A8%8B%E5%92%8C%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%8C%BA%E5%88%AB&spm=1018.2226.3001.4187)是Unity独特的,利用计数器IEnumerator和StartCorountine来调用协程

只不过看到这里的应该都是大多懂Unity协程的运行进程的,所以我就不细讲了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class IEnumeratorDOTween : MonoBehaviour
{
    Tween twn;
    void Start()
    {
        twn = transform.DOMove(new Vector3(2, 2, 2), 2f).SetLoops(3,LoopType.Yoyo);
        StartCoroutine(waitFuc()); 
    }

    IEnumerator waitFuc()
    {
        //等待动画完成
        yield return twn.WaitForCompletion();
        //执行几次循环以后
        yield return twn.WaitForElapsedLoops(2);
        //等待销毁以后
        yield return twn.WaitForKill();
        //等待运行的多少时间后
        yield return twn.WaitForPosition(1.5f);
        //等待到重新来的时候
        yield return twn.WaitForRewind();
        //等待起始化的时候
        yield return twn.WaitForStart();
    }
    
}

十一丶路径动画

  这点有些难以讲解,推荐看我一开头推荐的老师讲的视频,然后以下是路径动画创建的整个过程:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using System.Linq;
using System;
public class PathAnimationDOTween : MonoBehaviour
{
    //创建一个路径编辑器
    public Transform[] listTrans;
    void Start()
    {
        var listPosition = listTrans.Select(u => u.position).ToArray();
        transform.DOPath(listPosition, 5f,PathType.Linear,PathMode.Full3D,10,Color.red)
            .SetOptions(true,AxisConstraint.None,AxisConstraint.Y) //bool 是否为闭口,锁定哪个轴以及哪个 转向
            .SetLookAt(new Vector3(0,0,0)); //一直看到0,0,0这个点
        //SetLokkAt(0)一直看前方,数值为0到1,0.3是和正前方的角度的夹角

        //SetOptions(bool是否是封闭路径,AxisConstrains.锁定哪个轴,AxisContstrains.锁定哪个角度)
    }

    
}

然后把我们创建的八个新方块拖进来List,然后点击运行,会发现已经创建好路径了,接下来你的Cube将按照设置的参数属性等进行移动


学习产出:

 以上便是本人当前对DOTween的所有理解,如果你能看到最后说明你耐心是真的NB。

接下来的文章会对学到DOTween进行综合应用,感谢支持。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐