下面学些下NGUI的TweenPosition位移动画,一般的位移动画需求分为不相对于Anchor锚点的位移动画和相对于Anchor的位移动画(主要看是否考虑屏幕分辨率),下面介绍两种游戏中最常用的不相对于Anchor的TweenPosition用法:
用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画
用法2.在游戏中需要动态创建带有TweenPosition组件动画的对象,对象创建、移动、到达指定位置、销毁的过程。eg.游戏中玩家吃金币,迟到金币后转换为分数,分数播放一个TweenPosition组件动画,从玩家位置移动到分数标签位置,到达分数后,销毁。
用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画
这种用法最简单,设置连个位置,播放动画即可
效果图如下:
可以把控件隐藏,在程序中开启动画:
TweenPosition tp = tweenObject.GetComponent<TweenPosition>(); tp.PlayForward();
效果图如下:
需要注意几点:
1.要动态生成的分数对象,需要做成预制体,放到Resources/Prefabs目录下,Scene场景中没有备份
2.TweenPositon不要开启,在程序中来控制播放动画的时机
创建一个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); }