ローディング


Unityでローディングをする際のテスト。基本的にはWWWクラスで簡単に処理ができる。FlashでいうURLLoaderのような感じだけどもう少し簡易的に扱える。
今回は画像ならGUI.Boxで画像を表示し、音ならAudioSourceで音を鳴らし、それ以外であればGUI.TextFieldにてテキストを表示させるようにしてみた。
音についてはUnityはmp3を外から取ってきて鳴らすというのはサポートされていないそうで非圧縮音源かoggフォーマットのみ。

基本的な部分はすごく簡単で

/**
 * データのロード。
 */
private IEnumerator LoadData(string url) {
	this.www = new WWW(url);

	yield return this.www;

	// ダウンロード後の処理
}

こんなメソッドを用意してあげて、あとは呼び出すだけ。
ローディング状況はWWW.progressで取れる。
エラーについてはWWW.errorがnullでなければエラーが発生している。
Flashと同様に別のドメインのファイルを見にいくときにはcrossdomain.xmlの設置が必要になってくる。

全体のソースは

using UnityEngine;
using System.Collections;
using System.IO;

/**
 * WWWによるロードのテスト。
 */
public class LoadingTest : MonoBehaviour {
	/**
	 * 入力テキスト。
	 */
	private string inputTxt = "http://farm5.static.flickr.com/4147/5222317796_f5533d3b16_o.jpg";

	/**
	 * ローディング中かどうか。
	 */
	private enum LoadingStatus {
		NONE,
		LOADING,
		LOADED,
		ERROR
	};

	private LoadingStatus loading = LoadingStatus.NONE;

	/**
	 * 読み込みを行う。
	 */
	private WWW www;

	/**
	 * ダウンロードされたファイルタイプ。
	 */
	private enum FileType {
		NONE,
		TXT,
		IMAGE,
		SOUND
	}

	private FileType downloadType;

	/**
	 * AudioSource.
	 */
	private AudioSource audioSource;

	/**
	 * エラー待ちフラグ。
	 */
	private bool errorWaitFlag = false;

	/**
	 * Awake.
	 */
	public void Awake() {
		this.audioSource = this.GetComponent<AudioSource>();
	}

	/**
	 * OnGUI.
	 */
	public void OnGUI() {
		// ダウンロード開始前
		if (this.loading == LoadingStatus.NONE) {
			this.inputTxt = GUI.TextField(new Rect(Screen.width / 2 - 250, Screen.height / 2 - 15, 500, 30), this.inputTxt);

			if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height / 2 + 50 - 15, 100, 30), "Load")) {
				StartCoroutine(this.LoadData());
			}
		}
		// ダウンロード中
		else if (this.loading == LoadingStatus.LOADING) {
			GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 15, 100, 30), "Loading...");
			GUI.Label(new Rect(Screen.width / 2 - 50 + 20, Screen.height / 2 + 30 - 15, 100, 30), (int)(this.www.progress * 100) + "%");
		}
		// ダウンロード完了
		else if (this.loading == LoadingStatus.LOADED) {
			// 画像
			if (this.downloadType == FileType.IMAGE) {
				GUI.Box(new Rect(0, 0, Screen.width, Screen.height - 50), this.www.texture);
			}
			// サウンド
			else if (this.downloadType == FileType.SOUND) {
				if (!this.audioSource.isPlaying) {
					if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height /2 - 15, 100, 30), "Play Sound")) {
						this.audioSource.Play();
					}
				}
				else {
					if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height /2 - 15, 100, 30), "Stop Sound")) {
						this.audioSource.Stop();
					}
				}
			}
			// その他
			else {
				string outTxt = this.www.text;
				if (outTxt.Length > 1000) {
					outTxt = outTxt.Substring(0, 1000);
				}

				GUI.TextField(new Rect(0, 0, Screen.width, Screen.height - 50), outTxt);
			}
			// リセットボタン
			if (GUI.Button(new Rect(Screen.width / 2 - 50, Screen.height - 40, 100, 30), "Reset")) {
				this.Reset();
			}
		}
		// ダウロードエラー
		else if (this.loading == LoadingStatus.ERROR) {
			GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 15, 600, 30), this.www.error);

			if (!this.errorWaitFlag) {
				StartCoroutine(this.WaitAndReset());
			}
		}
	}

	/**
	 * データのロード。
	 */
	private IEnumerator LoadData() {
		this.loading = LoadingStatus.LOADING;

		this.www = new WWW(this.inputTxt);

		// 拡張子からタイプ決定
		string ext = Path.GetExtension(this.www.url);

		// 画像
		if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".bmp") {
			this.downloadType = FileType.IMAGE;
		}
		// サウンド
		else if (ext == ".wav" || ext == ".aif" || ext == ".aiff" || ext == ".ogg") {
			this.downloadType = FileType.SOUND;
		}
		// その他
		else {
			this.downloadType = FileType.TXT;
		}


		yield return this.www;

		if (this.www.error != null) {
			this.loading = LoadingStatus.ERROR;
			return false;
		}

		// サウンド割り当て
		if (this.downloadType == FileType.SOUND) {
			this.audioSource.clip = this.www.audioClip;
		}

		this.loading = LoadingStatus.LOADED;
	}

	/**
	 * エラー待ち。
	 */
	private IEnumerator WaitAndReset() {
		this.errorWaitFlag = true;

		yield return new WaitForSeconds(2.0f);

		this.Reset();
	}

	/**
	 * リセット。
	 */
	private void Reset() {
		if (this.downloadType == FileType.SOUND) {
			this.audioSource.Stop();
			this.audioSource.clip = null;
		}

		this.www = null;
		this.loading = LoadingStatus.NONE;
		this.downloadType = FileType.NONE;
		this.errorWaitFlag = false;
	}
}

こんな感じ。

>>プロジェクトファイルダウンロード

コメントを残す