読者です 読者をやめる 読者になる 読者になる

The jonki

呼ばれて飛び出てじょじょじょじょーんき

【NGUI】NGUIのUIPanelでClipアニメーション

こういうオサレな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;
	}
}