こういうオサレなWebとかゲームのキャラ選択とかでありそうなマスクアニメーションを自前で作りました。
環境
- Unity pro 4.3.4
- NGUI 3.5.6
- iTween
準備
適当なAtlasを用意し、表示したい数だけUIPanelとUISpriteをセットで作成します。UIPanelでSpriteをクリップするため、InspectorビューでClippingをSoftClipにしといてください。
MaskManager
UIRootにつけ、各PanelControllerスクリプトのAPIを叩いています。Targetsは各PanelのGameObjectです。フルスクリーンにする際に描画順を1番上に持ってくる必要があるので、今回は超適当に処理しているので参考にしないでください(汗)。またどれかをフルスクリーン表示にしたら、他のフルスクリーン表示のSpriteは元Clipサイズに戻すですが、それも面倒なので今回はやっていません。
using UnityEngine; using System.Collections; using System.Collections.Generic; public class MaskManager : MonoBehaviour { public GameObject[] Targets; private List<PanelController> clipList; private float sw = 1024f; private float sh = 576f; // Use this for initialization void Start () { clipList = new List<PanelController>(); foreach(var target in Targets) { clipList.Add(target.AddComponent<PanelController>()); } Init(); } // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.Alpha1)) { ShowFullImage(0); } else if(Input.GetKeyDown(KeyCode.Alpha2)) { ShowFullImage(1); } else if(Input.GetKeyDown(KeyCode.Alpha3)) { ShowFullImage(2); } else if(Input.GetKeyDown(KeyCode.Alpha4)) { ShowFullImage(3); } else if(Input.GetKeyDown(KeyCode.Alpha0)) { Init(); } } void Init() { for(int i=0; i<clipList.Count; i++) { var size = new Vector2((sw / clipList.Count), sh); var offset = new Vector2(-sw * 0.5f + (i + 0.5f) * (sw / clipList.Count), 0f); clipList[i].UpdateOffset(offset); clipList[i].UpdateSize(size); } } void ShowFullImage(int id) { for(int i =0; i<clipList.Count; i++) { if(i != id) { clipList[i].SetDepth(i); } else { clipList[i].SetDepth(clipList.Count); } } clipList[id].UpdateOffset(new Vector2(0f, 0f)); clipList[id].UpdateSize(new Vector2(sw, sh)); } }
PanelController
各UIPanelのGameObjectにAddComponentされます。UIPanelのClipをゴリゴリとiTweenでアニメーションしています。
using UnityEngine; using System.Collections; public class PanelController : MonoBehaviour { private UIPanel panel; static private float animTime = 0.6f; void Awake() { panel = GetComponent<UIPanel>(); } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } public void SetDepth(int depth) { panel.depth = depth; } public void UpdateSize(Vector2 size) { var current = new Vector2(panel.baseClipRegion.z, panel.baseClipRegion.w); iTween.ValueTo(gameObject, iTween.Hash("from", current, "to", size, "time", animTime, "onupdate", "OnUpdateSize")); } public void UpdateOffset(Vector2 offset) { iTween.ValueTo(gameObject, iTween.Hash("from", panel.clipOffset, "to", offset, "time", animTime, "onupdate", "OnUpdateOffset")); } private void OnUpdateSize(Vector2 size) { panel.baseClipRegion = new Vector4(0f, 0f, size.x, size.y); } private void OnUpdateOffset(Vector2 offset) { panel.clipOffset = offset; } }