【UnityAsset】MVVM 4 uGUI – uGUIにMVVM(Model-View-ViewModel)パターンを導入

2015/11/07

【AssetStore】MVVM 4 uGUI
【UnityAsset】MVVM 4 uGUI – デモ

ここではMVVM 4 uGUI(M4u)がどんなAssetか説明します。
M4uの使用方法については【UnityAsset】MVVM 4 uGUI – デモをご覧下さい。

スポンサーリンク
  

M4uとは

M4uは、uGUIにMVVM(Model-View-ViewModel)パターンをサポートしたAssetです。
M4uを使用することで、コード量を劇的に少なくすることが可能です。

動作環境

Unity5.0+
iOS 6.0+
Android 2.3+

使用方法

【UnityAsset】MVVM 4 uGUI – デモ

M4uについて

View(uGUI)の更新

Viewの更新を「従来のやり方」と「M4u適用後」で比較すると以下のようになります。

using UnityEngine;
using UnityEngine.UI;

class Demo : MonoBehaviour
{
	[SerializeField]Text idText;
	[SerializeField]Text nameText;
	User user = new User();

	void Start()
	{
		int id = 1;
		string name = "てんぷら";

		// データ更新
		user.Id = id;
		user.Name = name;

		// Viewへ反映
		idText.text = id.ToString();
		nameText.text = name;
	}
}

class User
{
	int id;
	string name;

	public int Id { get { return id; } set { id = value; } }
	public string Name { get { return name; } set { name = value; } }
}
using UnityEngine;
using M4u;

class Demo : MonoBehaviour
{
	User user = new User();

	void Start()
	{
		int id = 1;
		string name = "てんぷら";

		// データ更新
		user.Id = id;
		user.Name = name;

		// Viewへの反映必要なし!
	}
}

class User
{
	M4uProperty<int> id = new M4uProperty<int>();
	M4uProperty<string> name = new M4uProperty<string>();

	public int Id { get { return id.Value; } set { id.Value = value; } }
	public string Name { get { return name.Value; } set { name.Value = value; } }
}

従来のやり方の問題点

今までは「データ更新」→「View反映」の手順が必要でした。ただ、大抵の場合、「データ=View」になってる場合が多く、同じようなコードを2倍書く必要があったかと思います。また、データ更新の際は常にViewを気にしてプログラムする必要がありました。

M4u適用後のメリット

M4uを使用するとデータ更新後のViewへの反映が必要なくなります。MVVMのデータバイディングの仕組みを利用することで、Viewへの反映はM4uが自動的に行ってくれます。このメリットはたくさんありますが、一番はコード量が劇的に少なくなることです。今まで常に2倍必要だったコードが1度で済むようになり、スッキリします。

• コード量削減(無駄なコードを書く必要なし!)
• 開発生産性/保守性の向上(データの修正だけでよくなる)
• プログラムがスッキリする(見通しが良くなる)

これらがM4uのメリットです。

M4uの使用例

ユーザーデータの更新

using UnityEngine;
using System;
using M4u;

class User
{
	M4uProperty<int> id = new M4uProperty<int>();
	M4uProperty<string> name = new M4uProperty<string>();
	M4uProperty<int> level = new M4uProperty<int>();
	M4uProperty<int> exp = new M4uProperty<int>();
	M4uProperty<int> gold = new M4uProperty<int>();
	M4uProperty<int> maouseki = new M4uProperty<int>();
	M4uProperty<string[]> friends = new M4uProperty<string[]> ();
	M4uProperty<DateTime> recoveryAt = new M4uProperty<DateTime>();
	M4uProperty<DateTime> loginAt = new M4uProperty<DateTime>();

	public int Id { get { return id.Value; } set { id.Value = value; } }
	public string Name { get { return name.Value; } set { name.Value = value; } }
	public int Level { get { return level.Value; } set { level.Value = value; } }
	public int Exp { get { return exp.Value; } set { exp.Value = value; } }
	public int Gold { get { return gold.Value; } set { gold.Value = value; } }
	public int Maouseki { get { return maouseki.Value; } set { maouseki.Value = value; } }
	public string[] Friends { get { return friends.Value; } set { friends.Value = value; } }
	public DateTime RecoveryAt { get { return recoveryAt.Value; } set { recoveryAt.Value = value; } }
	public DateTime LoginAt { get { return loginAt.Value; } set { loginAt.Value = value; } }
}

ユーザデータを画面に表示する機会は多いです。その場合、データの数だけViewの操作が必要になり、しかも実際はデータの更新が必要なだけで、Viewへの反映は同じことを繰り返し書いてることが多いです。
M4uを使用すればデータの更新だけで済むようになり、無駄な記述がなくなります(バグの抑止にも繋がります)。

※実際にはUnityエディタ上でのバインド設定が必要ですが、ここでは省略しています(詳しくは使用方法をご確認下さい)

ステータスによって表示を切り替えたい場合

using UnityEngine;
using System;
using M4u;

enum DialogType { Notice, Confirm }

class Dialog : MonoBehaviour
{
	M4uProperty<DialogType> type = new M4uProperty<DialogType>();
	M4uProperty<string> message = new M4uProperty<string>("");
	M4uProperty<string> positive = new M4uProperty<string>("");
	M4uProperty<string> negative = new M4uProperty<string>("");
	Action<Dialog> onPositive;
	Action<Dialog> onNegative;

	public DialogType Type { get { return type.Value; } set { type.Value = value; } }
	public string Message { get { return message.Value; } set { message.Value = value; } }
	public string Positive { get { return positive.Value; } set { positive.Value = value; } }
	public string Negative { get { return negative.Value; } set { negative.Value = value; } }
	public Action<Dialog> OnPositive { get { return onPositive; } set { onPositive = value; } }
	public Action<Dialog> OnNegative { get { return onNegative; } set { onNegative = value; } }

	public static Dialog Create(DialogType type)
	{
		var dialog = ((GameObject)Instantiate(Resources.Load("Dialog"))).GetComponent<Dialog>();
		dialog.Type = type;
		dialog.transform.localScale = Vector3.zero;
		return dialog;
	}

	public void Show()
	{
		transform.localScale = Vector3.one;
	}

	public void Hide()
	{
		Destroy (gameObject);
	}

	public void OnClickPositive()
	{
		if(onPositive != null) onPositive(this);
	}

	public void OnClickNegative()
	{
		if(onNegative != null) onNegative(this);
	}
}

enumの値で表示を切り替えたい時はしばしばあります。上の例だとDialogTypeによって、ボタンの数を変化させたりなど。
こういう場合、Viewの操作が必要なくなるのでプログラムがスッキリします。

更新が頻繁でいろいろな場所で表示されるオブジェクト

using UnityEngine;
using System.Collections.Generic;
using M4u;

class Character : M4uContext
{
	M4uProperty<int> id = new M4uProperty<int>();
	M4uProperty<string> name = new M4uProperty<string>();
	M4uProperty<CharacterType> type = new M4uProperty<CharacterType>();
	M4uProperty<Sprite> sprite = new M4uProperty<Sprite>();
	M4uProperty<int> hp = new M4uProperty<int>();
	M4uProperty<int> mp = new M4uProperty<int>();
	M4uProperty<List<string>> magics = new M4uProperty<List<string>>();
	M4uProperty<float> upStatus = new M4uProperty<float>();
	M4uProperty<float> downStatus = new M4uProperty<float>();

	public int Id { get { return id.Value; } set { id.Value = value; } }
	public string Name { get { return name.Value; } set { name.Value = value; } }
	public CharacterType Type { get { return type.Value; } set { type.Value = value; } }
	public Sprite Sprite { get { return sprite.Value; } set { sprite.Value = value; } }
	public int Hp { get { return hp.Value; } set { hp.Value = value; } }
	public int Mp { get { return mp.Value; } set { mp.Value = value; } }
	public List<string> Magics { get { return magics.Value; } set { magics.Value = value; } }
	public float UpStatus { get { return upStatus.Value; } set { upStatus.Value = value; } }
	public float DownStatus { get { return downStatus.Value; } set { downStatus.Value = value; } }
}

enum CharacterType { Yusha, Monster, NPC }

M4uはデータ更新が多い場合に真価を発揮します。
例えば、キャラクターのデータは事あるごとに変更されます。今までだと、更新箇所が増える度に「Viewの参照を保持」->「View反映のコード記述」という手順が必要でした。
これらがM4uを使えば一切なくなります。しかも上の例だと、CharacterをM4uContextで継承させていますが、こうすることでScrollViewのアイテムにそのままデータを結びつける事が可能です(使用方法CollectionBinding参考)。
CollectionBindingはとても強力な機能ですので、是非ご確認下さい。

Asset誕生秘話

実はM4uには元ネタがあります。

NData
Unity 〜NDATA その1 MVVMについて〜

自分の以前のUnityプロジェクトでNDataを使用していました。NDataはNGUIにMVVMを適用したAssetで、とても便利で、NDataなしでは今後開発できないとまで思ってました。
そんなNDataですが、2014年を最後に更新が停止しています。NDataの開発会社がAssetStoreから撤退した可能性があります。

そこで誕生したのがM4uです。M4uはNDataのuGUI版なのです。

最後に

M4uは、自分が開発したチャリで来た。カメラや外部プロジェクトでも採用されている実績があります。開発力を上げたい方は是非ご使用下さい。

M4uを宜しくお願いします。

スポンサーリンク