[置顶] 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)

下面学些下NGUI的TweenPosition位移动画,一般的位移动画需求分为不相对于Anchor锚点的位移动画和相对于Anchor的位移动画(主要看是否考虑屏幕分辨率),下面介绍两种游戏中最常用的不相对于Anchor的TweenPosition用法:

用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画

用法2.在游戏中需要动态创建带有TweenPosition组件动画的对象,对象创建、移动、到达指定位置、销毁的过程。eg.游戏中玩家吃金币,迟到金币后转换为分数,分数播放一个TweenPosition组件动画,从玩家位置移动到分数标签位置,到达分数后,销毁。


用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画


这种用法最简单,设置连个位置,播放动画即可

[置顶] 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)_第1张图片


效果图如下:

[置顶] 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)_第2张图片

可以把控件隐藏,在程序中开启动画:

TweenPosition tp = tweenObject.GetComponent<TweenPosition>();
tp.PlayForward();


用法2.在游戏中需要动态创建带有TweenPosition组件动画的对象,对象创建、移动、到达指定位置、销毁的过程。eg.游戏中玩家吃金币,迟到金币后转换为分数,分数播放一个TweenPosition组件动画,从玩家位置移动到分数标签位置,到达分数后,销毁。


效果图如下:

[置顶] 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)_第3张图片


需要注意几点:

1.要动态生成的分数对象,需要做成预制体,放到Resources/Prefabs目录下,Scene场景中没有备份

2.TweenPositon不要开启,在程序中来控制播放动画的时机

[置顶] 【Unity3D游戏开发】NGUI之不相对于Anchor的位移动画TweenPosition (上) (二)_第4张图片


创建一个PlayerEatScore.cs,绑定按钮上或UIRoot上都可以,代码如下:

using UnityEngine;
using System;
using System.Collections;

public class PlayerEatCoin : MonoBehaviour {

	private GameObject addScorePrefab; 		//Add score prefab
	private UILabel totalScoreLabel;  // 总分数Label
	private UIButton btn;

	private int totalScore; 		  // 总分数
	private int score; 				  // 添加的分数
	
	void Awake() {
		// 预先创建好常用的得分Prefab
		addScorePrefab = Resources.Load("Prefabs/AddScore") as GameObject;
	}
	
	void Start () {
		totalScore = 10000;
		totalScoreLabel = GameObject.Find("TotalScore").GetComponent<UILabel>();
		totalScoreLabel.text = totalScore.ToString();

		btn = GameObject.Find("BtnPlayerEatScore").GetComponent<UIButton>();
		
		// 设置按钮响应函数
		EventDelegate.Add(btn.onClick, AddScore);
	}
	
	void AddScore() {
		// 克隆得分GameObject
		GameObject addScoreClone = (GameObject)Instantiate(addScorePrefab, new Vector3(0, 0, 0), transform.rotation);
		UILabel label = addScoreClone.GetComponent<UILabel>();
		
		// 随机得分数
		score = UnityEngine.Random.Range(100, 300);
		label.text = score.ToString();
		
		// 获取TweenPosition对象
		TweenPosition tp = addScoreClone.GetComponent<TweenPosition>();
		
		// 设置To的坐标值,该值为NGUI的坐标系的值,所以需要逆转world坐标值transform.InverseTransformPoint
		tp.to = transform.InverseTransformPoint(totalScoreLabel.transform.position);
		Debug.Log(tp.to.ToString());
		
		// 设置动画播放结束后的回调函数
		EventDelegate.Add(tp.onFinished, ()=> {
			ScoreMoveFinished(addScoreClone, score);
		});

		// 在Inspector窗口Tween Position勾选去掉了脚本名字那里的复选框,所以Tween Position不会执行,需要手动Play
		tp.PlayForward();
	}
	
	void ScoreMoveFinished(GameObject label, int sc) {
		Debug.Log ("-----callback score:" + sc);
		totalScore += sc;
		totalScoreLabel.text = totalScore.ToString();
		
		// 使用传参 和TweenPosition.current的功能一样
		if (label != TweenPosition.current.gameObject) {
			Debug.Log("Param object not equal TweenPosition.current!");
		}
		
		// 销毁播放动画的对象
		Destroy(TweenPosition.current.gameObject);
		//Destroy(label.gameObject);
	}
}


上面的代码有几点需要注意:

1.预制体动态生成,预制体的目录位置

2.TweenPositon动画的回调传参数可以用一个lambda函数来解决

<span style="white-space:pre">	</span>EventDelegate.Add(tp.onFinished, ()=> {
			ScoreMoveFinished(addScoreClone, score);
		});

3.回调中的TweenPosition.current对象就是当前回调的TweenPosition对象,不通过参数传递也可以,这是新NGUI的通常用法。

<span style="white-space:pre">	</span>void ScoreMoveFinished(GameObject label, int sc) {
		// 使用传参 和TweenPosition.current的功能一样
		if (label != TweenPosition.current.gameObject) {
			Debug.Log("Param object not equal TweenPosition.current!");
		}
		
		// 销毁播放动画的对象
		Destroy(TweenPosition.current.gameObject);
		//Destroy(label.gameObject);
	}




你可能感兴趣的:(unity,NGUI,Tween,位移动画,TweenPosition)