【Unity学习笔记】DOTween(2)官方案例

本文中大部分内容学习来自DOTween官方文档

此处无法展示动图(懒得录GIF),请下载官方案例场景自行学习

文章目录

  • [场景1 基本补间](#场景1 基本补间)
  • [场景2 动态补间](#场景2 动态补间)
  • [场景3 Shader修改](#场景3 Shader修改)
  • [场景4 路径拟合运动](#场景4 路径拟合运动)
  • [场景5 序列播放](#场景5 序列播放)
  • [场景6 UGUI](#场景6 UGUI)

场景1 基本补间

案例一展示了最基础的一些用法:

csharp 复制代码
	IEnumerator Start()
	{
		// Start after one second delay (to ignore Unity hiccups when activating Play mode in Editor)
		yield return new WaitForSeconds(1);

		// Let's move the red cube TO 0,4,0 in 2 seconds
		redCube.DOMove(new Vector3(0,4,0), 2);

		// Let's move the green cube FROM 0,4,0 in 2 seconds
		greenCube.DOMove(new Vector3(0,4,0), 2).From();
		
		// Let's move the blue cube BY 0,4,0 in 2 seconds
		blueCube.DOMove(new Vector3(0,4,0), 2).SetRelative();

		// Let's move the purple cube BY 6,0,0 in 2 seconds
		// and also change its color to yellow.
		// To change its color, we'll have to use its material as a target (instead than its transform).
		purpleCube.DOMove(new Vector3(6,0,0), 2).SetRelative();
		// Also, let's set the color tween to loop infinitely forward and backwards
		purpleCube.GetComponent<Renderer>().material.DOColor(Color.yellow, 2).SetLoops(-1, LoopType.Yoyo);
	}

解读一下代码,redCube的移动是在两秒内移动到了指定坐标0,4,0,而greenCube移动带有From方法,则是从坐标0,4,0移动到原坐标。blueCube指定了SetRelative,则会以自身坐标为原点,移动到相对于自身坐标轴的0,4,0坐标上去。

而purpleCube除了应用Move的坐标变换,还将其组件的材质颜色进行了修改,使其由紫色变为黄色,并用SetLoops将循环模式设置为了-1,LoopType.Yoyo,第一个参数代表循环次数,-1代表了无限循环,第二个参数则代表了循环曲线模式。


场景2 动态补间

场景2实现了Follower对Followed的实时跟踪

csharp 复制代码
public class Follow : MonoBehaviour
{
	public Transform target; // Target to follow
	Vector3 targetLastPos;
	Tweener tween;

	void Start()
	{
		// First create the "move to target" tween and store it as a Tweener.
		// In this case I'm also setting autoKill to FALSE so the tween can go on forever
		// (otherwise it will stop executing if it reaches the target)
		tween = transform.DOMove(target.position, 2).SetAutoKill(false);
		// Store the target's last position, so it can be used to know if it changes
		// (to prevent changing the tween if nothing actually changes)
		targetLastPos = target.position;
	}

	void Update()
	{
		// Use an Update routine to change the tween's endValue each frame
		// so that it updates to the target's position if that changed
		if (targetLastPos == target.position) return;
		// Add a Restart in the end, so that if the tween was completed it will play again
		tween.ChangeEndValue(target.position, true).Restart();
		targetLastPos = target.position;
	}
}

简单三行代码,轻松实现,效果比德芙还丝滑,用SetAutoKill(false)确保Tween不会被自动回收,使用targetLastPos来每帧更新追踪(移动)的目标坐标,使用ChangeEndValue(target.position, true)来改变Tween的结束位置,第一个参数指定结束位置的值,第二个参数指定是否重新移动要从初始设置的值开始(还有一个重载函数public abstract Tweener ChangeEndValue(object newEndValue, float newDuration = -1, bool snapStartValue = false,第二个float值决定是否设置新的Duration时长)。

最后使用Restart()来重新开启补间动画。


场景3 Shader修改

csharp 复制代码
public class Materials : MonoBehaviour
{
	public GameObject target;
	public Color toColor;

	Tween colorTween, emissionTween, offsetTween;

	void Start()
	{
		// NOTE: all tweens will be created in a paused state, so they can be toggled via the UI

		// Store the material, since we will tween that
		Material mat = target.GetComponent<Renderer>().material;

		// COLOR
		colorTween = mat.DOColor(toColor, 1).SetLoops(-1, LoopType.Yoyo).Pause();

		// EMISSION
		// Note that the float value you see in Unity's inspector, next to the emission's color,
		// doesn't really exist in the shader (it's generated by Unity's inspector and applied to the material's color),
		// se we have to tween the full _EmissionColor.
		emissionTween = mat.DOColor(new Color(0, 0, 0, 0), "_EmissionColor", 1).SetLoops(-1, LoopType.Yoyo).Pause();

		// OFFSET
		// In this case we set the loop to Incremental and the ease to Linear, because it's cooler
		offsetTween = mat.DOOffset(new Vector2(1, 1), 1).SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental).Pause();
	}

	// Toggle methods (called by UI events)

	public void ToggleColor()
	{
		colorTween.TogglePause();
	}

	public void ToggleEmission()
	{
		emissionTween.TogglePause();
	}

	public void ToggleOffset()
	{
		offsetTween.TogglePause();
	}
}

案例三中介绍了对shader中的材质的各种值的补间变化,定义了colorTween,emissionTween,ToggleOffset三个Tween的补间。DO方法都是相似的,需要注意的是emissionTween由于是直接改变Shader中的值,所以用字符串读取了该Shader中的_EmissionColorSetEase(Ease.Linear)设置了增长类型并设定为线性的。

所有的Tween在初始化时设置了Pause(),当我们点击按钮时,触发TogglePause()方法,如果正在播放则暂停,如果暂停则播放。


场景4 路径拟合运动

场景4允许我们自定义路径和坐标,让物体沿着坐标点拟合的路径进行运动

csharp 复制代码
public class Paths : MonoBehaviour
{
	public Transform target;
	public PathType pathType = PathType.CatmullRom;
	public Vector3[] waypoints = new[] {
		new Vector3(4, 2, 6),
		new Vector3(8, 6, 14),
		new Vector3(4, 6, 14),
		new Vector3(0, 6, 6),
		new Vector3(-3, 0, 0)
	};

	void Start()
	{
		// Create a path tween using the given pathType, Linear or CatmullRom (curved).
		// Use SetOptions to close the path
		// and SetLookAt to make the target orient to the path itself
		Tween t = target.DOPath(waypoints, 4, pathType)
			.SetOptions(true)
			.SetLookAt(0.001f);
		// Then set the ease to Linear and use infinite loops
		t.SetEase(Ease.Linear).SetLoops(-1);
	}
}

想要拟合出路径,只需要设置好坐标点数组Vector3[],然后设定补间时间,最后设定拟合路径的曲线类型pathType,默认是线性的。使用SetOptions来设定路径是否闭合,(注意,SetOptions是一个很特别的方法,对于不同的DO方法,对应的SetOptions有不同的参数,具体还是得看官方文档)。DOPath也有重载方法,学会查看引用和查阅官方文档是很重要的事情!


场景5 序列播放

csharp 复制代码
public class Sequences : MonoBehaviour
{
	public Transform cube;
	public float duration = 4;

	IEnumerator Start()
	{
		// Start after one second delay (to ignore Unity hiccups when activating Play mode in Editor)
		yield return new WaitForSeconds(1);

		// Create a new Sequence.
		// We will set it so that the whole duration is 6
		Sequence s = DOTween.Sequence();
		// Add an horizontal relative move tween that will last the whole Sequence's duration
		s.Append(cube.DOMoveX(6, duration).SetRelative().SetEase(Ease.InOutQuad));
		// Insert a rotation tween which will last half the duration
		// and will loop forward and backward twice
		s.Insert(0, cube.DORotate(new Vector3(0, 45, 0), duration / 2).SetEase(Ease.InQuad).SetLoops(2, LoopType.Yoyo));
		// Add a color tween that will start at half the duration and last until the end
		s.Insert(duration / 2, cube.GetComponent<Renderer>().material.DOColor(Color.yellow, duration / 2));
		// Set the whole Sequence to loop infinitely forward and backwards
		s.SetLoops(-1, LoopType.Yoyo);
	}
}

使用序列可以执行多个Tween,正常Append的话就是像委托一样的一个一个地执行,(感兴趣可以试试下面的代码),这样子的话整个动画的执行就是每个Append中的Tween依次执行动画,也就是先移动,再旋转,再变色,而执行完毕之后由于设置了loop,整个序列动画会再倒放一次,直到回到原始状态又开始播放。

而使用Insert方法,我们可以设定什么时间点可以直接播放Tween补间动画,由第一个参数指定播放的时间即可。这样就可以再移动的同时,也会旋转和变色了。并且Sequence作为一个整体,只有全部动画播完才会循环倒放,而不是各个Tween独自计算播放循环,各个Tween是相关联的。

csharp 复制代码
public class Sequences : MonoBehaviour
{
	public Transform cube;
	public float duration = 4;

	IEnumerator Start()
	{
		// Start after one second delay (to ignore Unity hiccups when activating Play mode in Editor)
		yield return new WaitForSeconds(1);

		// Create a new Sequence.
		// We will set it so that the whole duration is 6
		Sequence s = DOTween.Sequence();
		// Add an horizontal relative move tween that will last the whole Sequence's duration
		s.Append(cube.DOMoveX(6, duration).SetRelative().SetEase(Ease.InOutQuad));
		// Insert a rotation tween which will last half the duration
		// and will loop forward and backward twice
		s.Append( cube.DORotate(new Vector3(0, 45, 0), duration / 2).SetEase(Ease.InQuad).SetLoops(2, LoopType.Yoyo));
		// Add a color tween that will start at half the duration and last until the end
		s.Append(cube.GetComponent<Renderer>().material.DOColor(Color.yellow, duration / 2));
		// Set the whole Sequence to loop infinitely forward and backwards
		s.SetLoops(-1, LoopType.Yoyo);
	}
}

场景6 UGUI

该场景展示了一些使用DOTween实现的常见的动画效果,包括图像渐入渐出,循环环状载入条,循环条状条,字体变化等等。

csharp 复制代码
public class UGUI : MonoBehaviour
{
	public Image dotweenLogo, circleOutline;
	public Text text, relativeText, scrambledText;
	public Slider slider;

	void Start()
	{
		// All tweens are created in a paused state (by chaining to them a final Pause()),
		// so that the UI Play button can activate them when pressed.
		// Also, the ones that don't loop infinitely have the AutoKill property set to FALSE,
		// so they won't be destroyed when complete and can be resued by the RESTART button

		// Animate the fade out of DOTween's logo
		dotweenLogo.DOFade(0, 1.5f).SetAutoKill(false).Pause();

		// Animate the circle outline's color and fillAmount
		circleOutline.DOColor(RandomColor(), 1.5f).SetEase(Ease.Linear).Pause();
		circleOutline.DOFillAmount(0, 1.5f).SetEase(Ease.Linear).SetLoops(-1, LoopType.Yoyo)
			.OnStepComplete(()=> {
				circleOutline.fillClockwise = !circleOutline.fillClockwise;
				circleOutline.DOColor(RandomColor(), 1.5f).SetEase(Ease.Linear);
			})
			.Pause();

		// Animate the first text...
		text.DOText("This text will replace the existing one", 2).SetEase(Ease.Linear).SetAutoKill(false).Pause();
		// Animate the second (relative) text...
		relativeText.DOText(" - This text will be added to the existing one", 2).SetRelative().SetEase(Ease.Linear).SetAutoKill(false).Pause();
		// Animate the third (scrambled) text...
		scrambledText.DOText("This text will appear from scrambled chars", 2, true, ScrambleMode.All).SetEase(Ease.Linear).SetAutoKill(false).Pause();

		// Animate the slider
		slider.DOValue(1, 1.5f).SetEase(Ease.InOutQuad).SetLoops(-1, LoopType.Yoyo).Pause();
	}

	// Called by PLAY button OnClick event. Starts all tweens
	public void StartTweens()
	{
		DOTween.PlayAll();
	}

	// Called by RESTART button OnClick event. Restarts all tweens
	public void RestartTweens()
	{
		DOTween.RestartAll();
	}

	// Returns a random color
	Color RandomColor()
	{
		return new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1);
	}
}

使用DOFade实现渐隐效果,第一个是alpha值,第二个参数是补间时间。

环状进度条变化的代码很巧妙,首先使用DOFillAmount对image组件进行百分比的填充,这是基于组件本身的填充模式的,在本场景中该组件的填充模式是顺时针,但是SetLoops()是会倒放补间动画的,也就是刚开始播放时,环状进度条顺时针减少,接着如果倒放就会变成逆时针增加,但是顺时针增加会比逆时针增加好看很多,所以在这里用了OnStepComplete来判断当补间动画播放完毕的时候,添加一个委托,让指针方向取反,顺时针就成了逆时针,而逆时针对应倒放就是顺时针,从而实现了顺时针减少进度条,倒放时顺时针增加进度条。而之所以重新定义了DOColor的补间动画,是希望颜色能够始终随机变化,而不是倒放回去。

DOText展现了三种文字变化的模式,分别对应逐字变化,空白打字,乱码显字三种字体的显示效果。按照上述代码设置即可。

最后就是PlayAllRestartAll,这两个方法控制所有的Tween的行为。


使用DOTween,能够简单地实现强大的视觉效果,真的牛b。

相关推荐
大筒木老辈子26 分钟前
Linux笔记---协议定制与序列化/反序列化
网络·笔记
草莓熊Lotso33 分钟前
【C++】递归与迭代:两种编程范式的对比与实践
c语言·开发语言·c++·经验分享·笔记·其他
我爱挣钱我也要早睡!3 小时前
Java 复习笔记
java·开发语言·笔记
知识分享小能手6 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
汇能感知8 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun8 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao9 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾9 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT10 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa10 小时前
HTML和CSS学习
前端·css·学习·html