标签:ngui tweenpositon 位移动画 分辨率适配 uianchor
Unity中的UI我们采用的是NGUI,NGUI的界面位移动画,我们一般使用的是TweenPosition。
一种是简单的相对位移,不考虑分辨率适配问题,只需要简单的从位置A到位置B,已经在文中介绍了:
【Unity NGUI游戏开发之二】TweenPosition位移动画(一):不相对于Anchor的位移动画
另外一种是考虑到屏幕分辨率适配的位移动画,我们游戏中大多遇到的是这种情况。
eg.我们想让一个UI从屏幕外沿着屏幕的左边移动到屏幕的中央,TweenPositon播放动画,在960*640下正合适从屏幕外到屏幕内,那么在1136*640、2048*2536等各种分辨率下是否正常还是会穿帮?答案是肯定会穿帮的。
在这里我们对TweenPosition进行了扩展。屏幕的适配方案我们依旧采用NGUI默认的解决方案。
当使用TweenPosition播放动画,从屏幕外移动到屏幕内,TweenPosition需要Vector3的起始位置和终止位置,设置如下:
当改变分辨率或宽高比的时,还按照坐标来设置的话,效果就出错了:
4:3
16:9
通过脚本来根据分辨率计算起始坐标和终止坐标,效果也不理想
NGUI中有一个组件TweenTransform,允许移动一个object从A移动到B,A、B只需要有transform即可。通过A、B对象来记录移动的目标点。
将要移动的对象的UIAnchor(Anchor属性)相对位置去掉,将锚点设置给A、B对象。否则这个这个对象会一直相对于这个锚点对齐,播放动画不会有任何效果。
更改分辨率看效果:
4:3 和 16:9
效果在不同分辨率下都正常了,接下来我们就是实际应用了,工程中有一堆这些效果,如果每一个都这么设置一个A、B对象,无疑是非常繁琐的,在这里将TweenTransform脚本进行扩展,实现一个自动化处理。
创建一个接口脚本 TweenPositonEx.cs,添加到任何想相对于屏幕或父节点做位移动画的控件上。脚本接口简单,只需要A、B两个控件。
/**
TransformPostion的扩展:
1.可以根据游戏屏幕分辨率播放从A到B动画 eg. UI从屏幕外左边移动到屏幕中英
2.TweenTransformExEditor.cs中对编辑器进行定制,实现了功能自动化处理,节省开发时间
Added by Teng.
**/
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(TweenTransform))]
public class TweenTransformEx : MonoBehaviour {
public GameObject FromAnchor;
public GameObject ToAnchor;
}接下来是TweenPositonExEditor.cs,是TweenPositonEx.cs脚本的一个编辑器扩展,内部有些复杂,无需关心内容,也不需要添加到任何脚本行,只需要放到工程中即可。
/**
对TweenTransformEx.cs类的属性的编辑器定制,实现了功能自动化处理,节省开发时间
Added by Teng.
**/
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof (TweenTransformEx))]
public class TweenTransformHelperEditor : Editor {
private TweenTransformEx _tweener;
private void Awake() {
_tweener = (TweenTransformEx) target;
}
public override void OnInspectorGUI() {
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Create from anchor")) {
CreateAnchorFrom();
}
if (GUILayout.Button("Destroy")) {
DestroyAnchor(_tweener.FromAnchor);
}
EditorGUILayout.EndHorizontal();
_tweener.FromAnchor = (GameObject) EditorGUILayout.ObjectField(_tweener.FromAnchor, typeof (GameObject));
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Create to anchor")) {
CreateAnchorTo();
}
if (GUILayout.Button("Destroy")) {
DestroyAnchor(_tweener.ToAnchor);
}
EditorGUILayout.EndHorizontal();
_tweener.ToAnchor = (GameObject) EditorGUILayout.ObjectField(_tweener.ToAnchor, typeof (GameObject));
CreateAndApplyTweener();
UpdateUI();
}
private void CreateAndApplyTweener() {
bool toAnchorNotEqualsNull = _tweener.ToAnchor;
bool fromAnchorNotEqualsNull = _tweener.FromAnchor;
if (!fromAnchorNotEqualsNull) {
EditorGUILayout.HelpBox("From anchor not created!", MessageType.Warning);
}
else if (!toAnchorNotEqualsNull) {
EditorGUILayout.HelpBox("To anchor not created!", MessageType.Warning);
}
else {
if (GUILayout.Button("Apply to tween")) {
var tweenComponent = _tweener.GetComponent<TweenTransform>() ?? _tweener.gameObject.AddComponent<TweenTransform>();
tweenComponent.from = _tweener.FromAnchor.transform;
tweenComponent.to = _tweener.ToAnchor.transform;
tweenComponent.enabled = false;
}
}
}
private void UpdateUI() {
if (GUI.changed) {
EditorUtility.SetDirty(_tweener);
}
}
private void DestroyAnchor(GameObject gameObj) {
if (gameObj == null) {
return;
}
DestroyImmediate(gameObj);
}
private void CreateAnchorTo() {
var anchor = CreateAnchor("$anchorTo");
_tweener.ToAnchor = anchor;
}
private void CreateAnchorFrom() {
var anchor = CreateAnchor("$anchorFrom");
_tweener.FromAnchor = anchor;
}
private GameObject CreateAnchor(string anchorName) {
var anchorGameObj = new GameObject(anchorName);
anchorGameObj.transform.parent = _tweener.transform;
anchorGameObj.transform.localPosition = Vector3.zero;
anchorGameObj.transform.localScale = Vector3.one;
var widgetScript = anchorGameObj.AddComponent<UIWidget>();
widgetScript.width = widgetScript.height = 100;
return anchorGameObj;
}
}添加脚本到widget上,如下:
点击要播放动画的widget, 创建anchorTo和anchorFrom,点击【Apply to tween】,接下来只需要相对的调节anchorTo和anchorFrom的相对位置即可。
需要有以下几点注意:
1.要播放动画的widget控件不能有Anchor,最起码不能有OnUpdate的Anchor,否则会一直相对于Anchor设置位置,播放动画无任何效果,只需要调整A、B的Anchor即可。
2.要播放动画的widget控件在屏幕外的初始位置,可以设置OnStart的Anchor(仅执行一次),来确保肯定在屏幕外。
版权声明:本文为博主原创文章,未经博主允许不得转载。
【Unity NGUI游戏开发之三】TweenPosition位移动画(二):相对于UIAnchor不同分辨率下的完美适配位移动画
标签:ngui tweenpositon 位移动画 分辨率适配 uianchor
原文地址:http://blog.csdn.net/teng_ontheway/article/details/47070295