UI系统--DOTween实现

Jun 4, 2018


研究 DOTween 网站 http://dotween.demigiant.com/getstarted.php 网页, 它在 Specific settings 中 transform.DoMove 返回 Tween 对象。请实现该对象,实现对动作的持续管理。

DOTween是一款动画插件,使用协程的技术来实现动画效果,效率很高。

Image text


Tween的简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	public Transform transform;
	public Action<Tween> complete;
	public Coroutine coroutine;
	public int times;
	public Vector3 target;
	public float duration;
	public bool isPause;

	public Tween(Transform transform, Vector3 target, float duration) {
		this.transform = transform;
		this.target = target;
		this.duration = duration;
		this.isPause = false;
		this.times = 1;
	}

	public Tween SetComplete(Action<Tween> ac) {
		this.complete += ac;
		return this;
	}

	public Tween SetCoroutine(Coroutine coroutine) {
		this.coroutine = coroutine;
		return this;
	}

	public Tween SetLoops(int num) {
		this.times = num;
		return this;
	}

	public Tween Pause() {
		this.isPause = true;
		return this;
	}

	public Tween Continue() {
		this.isPause = false;
		return this;
	}

	public Tween Stop() {
		this.transform.GetComponent<MonoBehaviour> ().StopCoroutine (this.coroutine);
		return this;
	}

	public void OnComplete() {
		if (this.complete != null)
			this.complete (this);
	}

实现Transform和MonoBehaviour的扩展方法

使用扩展方法来实例化Tween、实现动画效果

DOMove 与 DOScale

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	public static IEnumerator DOMove(this MonoBehaviour mono, Tween tween)
	{
		Vector3 speed = (tween.target - tween.transform.position) / tween.duration;
		int times = 0;
		while (times++ < tween.times) {
			for (float f = tween.duration; f >= 0.0f; f -= Time.deltaTime)
			{
				tween.transform.Translate(speed * Time.deltaTime);
				yield return null;
				while (tween.isPause == true)
				{
					yield return null;
				}
			}
		}

		tween.OnComplete();
	}

	public static Tween DOMove(this Transform transform, Vector3 target, float duration)
	{
		MonoBehaviour mono = transform.GetComponent<MonoBehaviour>();
		Tween tween = new Tween(transform, target, duration);
		Coroutine coroutine = mono.StartCoroutine(mono.DOMove(tween));
		tween.SetCoroutine(coroutine);
		return tween;
	}

	public static IEnumerator DOScale(this MonoBehaviour mono, Tween tween)
	{
		Vector3 speed = (tween.target - tween.transform.localScale) / tween.duration;
		int times = 0;
		while (times++ < tween.times) {
			for (float f = tween.duration; f >= 0.0f; f -= Time.deltaTime) {
				tween.transform.localScale += speed*Time.deltaTime;
				yield return null;
				while (tween.isPause == true) {
					yield return null;
				}
			}
		}
		tween.OnComplete();
	}

	public static Tween DOScale(this Transform transform, Vector3 target, float time)
	{
		MonoBehaviour mono = transform.GetComponent<MonoBehaviour>();
		Tween tween = new Tween(transform, target, time);
		Coroutine coroutine = mono.StartCoroutine(mono.DOScale(tween));
		tween.SetCoroutine(coroutine);
		return tween;
	}

DORotate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	public static IEnumerator DORotate(this MonoBehaviour mono, Tween tween)
	{
		Vector3 speed = (tween.target - tween.transform.localScale) / tween.duration;
		int times = 0;
		while (times++ < tween.times) {
			for (float f = tween.duration; f >= 0.0f; f -= Time.deltaTime) {
				tween.transform.Rotate (speed * Time.deltaTime);
				yield return null;
				while (tween.isPause == true) {
					yield return null;
				}
			}
		}
		tween.OnComplete();
	}

	public static Tween DORotate(this Transform transform, Vector3 target, float time)
	{
		MonoBehaviour mono = transform.GetComponent<MonoBehaviour>();
		Tween tween = new Tween(transform, target, time);
		Coroutine coroutine = mono.StartCoroutine(mono.DORotate(tween));
		tween.SetCoroutine(coroutine);
		return tween;
	}

测试

1
2
3
4
5
6
7
8
9
10
11
	void Start () {
		transform.DOMove (new Vector3 (2, 2, 2), 2)
			.SetComplete ((a)=>{Debug.Log("Complete Move");});
		
		transform.DOScale (new Vector3 (2, 2, 2), 2)
			.SetComplete ((a)=>{Debug.Log("Complete Scale");});

		transform.DORotate (new Vector3 (0, 360, 0), 2)
			.SetComplete ((a)=>{Debug.Log("Complete Rotate");})
			.SetLoops(10);
	}

参考资料