uGUIでゲージを作った話

この記事は [CyberAgent エンジニア Advent Calendar 2014](http://www.adventar.org/calendars/358) 13日目の投稿です。

私が今携わっているプロジェクトでは、まだベータだったころのUnity4.6(uGUI)ベースで
開発がスタートしました。

色んな...色んなことがありましたが、今回はゲージを作った話をしたいと思います。

さて、ゲージを作るにあたって、デザイナーさんから頂いたデザインはこんなかんじでした。

![gauge.png](https://qiita-image-store.s3.amazonaws.com/0/8904/f5a3f99e-95e9-c8c4-c112-90e7444ed63a.png)

こちらをuGUIでどのように実装したかというお話です。

## fillSpriteでつくる
uGUIにはNGUI同様fillSprite機能があります。

![SS1.png](https://qiita-image-store.s3.amazonaws.com/0/8904/83c32dd1-f84e-1ae9-ffaa-8f344d249c7f.png)

上図のようにSpriteのImageTypeをFilledにするれば後はFillAmountを調整するだけで簡単にゲージが作れます。ただ...

![SS2.png](https://qiita-image-store.s3.amazonaws.com/0/8904/9e157657-eea9-3ba1-03a2-972206dc3bc4.png)

Fill MethodをHorizontalにすると90度でぶった切られてしまうのでこのようなゲージには使いづらいところです。

## Maskで作る
uGUIでは下図のようにMaskコンポーネントをアタッチしたImageの子にImageを置くことで
Maskをかけることが出来ます。

![SS3.png](https://qiita-image-store.s3.amazonaws.com/0/8904/ed7e90d1-cfc8-c452-4e53-f564a2e0fdec.png)

あとはMaskされたImageを左右にずらすことでゲージを表現することが出来ます。

ただ、このMaskを使うことでDrawCallが3消費されてしまうこと、
Androidの一部端末でMaskが効かないものがあるので、あまり多様はしたくありません。
(↑Maskの件はUnity4.6p1で対応されたそうです！)

## ポリゴン的に作る
uGUIのGraphicコンポーネントは、OutlineやShadowコンポーネントをアタッチすることで
それぞれ枠や影をつけることが出来ます。

これを見てみると、どうやらVertexをいじることで図形を描画出来るような雰囲気があります。
↓ShadowのSuperクラスであるVertexModifiersのソース
https://bitbucket.org/Unity-Technologies/ui/src/b914129e0b5bc9e9eb20af391ba99f659ec85a47/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs?at=4.6

ということでいじってみたのがこちら
OpenGLの教科書でよく見る奴が出来ました。

![SS4.png](https://qiita-image-store.s3.amazonaws.com/0/8904/48f68a8a-0491-0a74-33cd-a2965a1ae781.png)

ソースはこちら

```VBOImage.cs
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;

public class VBOImage : Image {

	protected override void OnFillVBO (List<UIVertex> vbo)
	{
		GenerateSprite (vbo, preserveAspect);
	}

	protected void GenerateSprite (List<UIVertex> vbo, bool unusedPreserveAspect)
	{
		UIVertex vert = UIVertex.simpleVert;
		vert.color = color;
		
		Vector4 dimension = new Vector4(0,0,100f,100f);
		float width = Mathf.Abs (dimension.x - dimension.z);
		float height = Mathf.Abs (dimension.y - dimension.w);

		var uv = Vector4.zero;
		
		// left bottom
		vert.position = new Vector3 (dimension.x, dimension.y);
		vert.uv0 = new Vector2 (uv.x, uv.y);
		vert.color = Color.red;
		vbo.Add (vert);
		
		// left top
		vert.position = new Vector3 (dimension.x + 100, dimension.w);
		vert.uv0 = new Vector2 (uv.x, uv.w);
		vert.color = Color.blue;
		vbo.Add (vert);
		
		// right top
		vert.position = new Vector3 (dimension.z - 0, dimension.w);
		vert.uv0 = new Vector2 (uv.z, uv.w);
		vert.color = Color.green;
		vbo.Add (vert);
		
		// right bottom
		vert.position = new Vector3 (dimension.z - 0, dimension.y);
		vert.uv0 = new Vector2 (uv.z, uv.y);
		vert.color = Color.white;
		vbo.Add (vert);
	}
}
```


これを応用して、
・4点を指定して平行四辺形を描画
・パーセンテージに合わせて頂点座標を変えることで長さを変更する
上記の2点を実装すればゲージの完成です。

![SS5.png](https://qiita-image-store.s3.amazonaws.com/0/8904/9c6ab48c-93a7-3dda-e76d-f4cfde6bfc15.png)
(↑はスーパー新卒のW先生がささっと実装してくれました！)

##まとめ

以上、uGUIでゲージを作った話でした。
Unityも4.6正式版がリリースされ、いよいよ実用段階になってきました。
今までNGUIを使っていた人も、Unity初めて！というひともこの年末年始に
触ってみてはいかがでしょうか？

では！