uFrame Document読んでみる

昔は90ドルしたuFrameがいつのまにか無料になりました。
uFrameはMVVMをNodeベースで設計できるビジュアルスクリプティングツールです。
![スクリーンショット 2016-08-16 1.20.09.png](https://qiita-image-store.s3.amazonaws.com/0/67575/203f1e6f-1b7e-0997-eb51-b01ec61ca43e.png)

Webサイトに繋がらなくなていたりオンラインドキュメントが読めなくなっていたりgithubリポジトリのCommitが1年くらいなかったり明らかなバグが放置されていたりと若干不安ではありますが、強力なMVVM制限によって(うまくやれば)堅実な実装ができるツールとなっています。

いまいちMVVMで綺麗に開発ができない僕にとってはMVVMベースでの開発を理解するよい手助けになると思うのでとりあえずドキュメントをやってみます。

読んでみるドキュメント(Get Started)は[こちら](https://github.com/InvertGames/uFrame.Documentation/blob/master/uFrameMVVM/tutorials/getting-started-for-uframe-mvvm-16/tutorial-1.md)
いつか
https://github.com/InvertGames/uFrame.Documentation/blob/master/uFrameMVVM/pages/home.md
もやってみようと思います。


##uFrame MVVM 1.6 Getting Started I
ver1.6です。
1.5や2.0もあるので注意です。
現在AssetStoreで配布されているuFrameは1.5と1.6が同封されています。

##Overview
このチュートリアルではuFrame MVVMのインストールの方法と使い方を紹介します。デフォルトプロジェクトからログイン時にエラーを出すところまでやっていきます。

###Steps
1. uFrame MVVM をインストールする方法
2. サンプルプロジェクトのセットアップする方法
3. ElementにPropertyを追加する方法
4. ViewをBindingする方法
5. ControllerのLogicを変更する方法
6. GUIとViewをつなげる方法
7. Final Testの実行

###所用時間
6~8分


##Transcript

###Introduction(初めに)
1.6 uFrame getting started guideへようこそ！すべてのガイドはuFrame MVVM 1.6サンプルプロジェクトをベースにしています。
すべてのパートはuFrame MVVMの機能をはっきりと説明しています。ほとんどのパートではサンプルを少しだけ変更するシンプルチェンジを提案して進めていきます。
このパートではuFrame MVVMのインストールの方法とサンプルプロジェクトのセットアップの方法を説明します。今回のパートでもシンプルチェンジをやってみましょう。ログイン画面で表示するエラーメッセージを作ってみましょう。

###How to install uFrame MVVM(インストールの方法)
Asset Storeを使うことでuFrame MVVMを他のAssetと同様にインストールすることができます。
簡単にインポートしてUnityの手順に従うだけ。
https://www.assetstore.unity3d.com/jp/#!/content/14381

uFrame MVVM 1.6は、Assets直下のuFrameMVVMフォルダ内にあります。中には２つのバージョンのuFrame MVVMがあります(1.5と1.6)。
![uframe_importedstate.png](https://qiita-image-store.s3.amazonaws.com/0/67575/e85d5556-bc92-1f63-4e26-5b28bed84a7b.png)

Version1.5はUnity互換性のために後方に送られました。もしuFrameにまだ慣れていないならぜひVersion1.6をダブルクリックしてインポートしてください。uFrameMVVMフォルダーはこのStep後にデリートすることができます。
このチュートリアルは1.6に基づいています。1.5のチュートリアルは[こちら](http://invertgamestudios.com/mvvm/overview)


###Learn how to setup default project(デフォルトプロジェクトをセットアップ)
uFrame MVVM1.6がインポートできたらWelcome画面が表示されます。自分でWelcome画面を開くためにはメニューからuFrame -> Welcome Screenを選択してください。
![uframe_welcome_screen_open.png](https://qiita-image-store.s3.amazonaws.com/0/67575/2075f3c9-a9fc-b9a5-8e43-a7e334e9690f.png)

Welcome画面では、サンプル(1)へのナビがあります。"SETUP EXAMPLE PROJECT"ボタンがあるのでクリックしましょう。("SETUP EXAMPLE PROJECT"ボタンの画像とクリック位置がずれています。クリック判定がある位置にマウスが乗るとカーソルが変わるので頑張って探しましょう;;)
![uframe_welcome_screen_goto.png](https://qiita-image-store.s3.amazonaws.com/0/67575/0774d860-7094-b838-822c-ffff03bbb2c3.png)
*"SETUP EXAMPLE PROJECT"ボタンをクリックした
<img width="464" alt="スクリーンショット 2016-08-16 2.02.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/c6b2f8d6-d043-a217-b407-96e0a5d0a424.png">

注意書きに従って、Example PackageをAssets以下にデプロイ(インポート)しましょう。そして全ての必要なシーンをBuild Settingsに追加しましょう。最後にIntroSceneを開きゲームを再生してみましょう。
![example_project_deployed.png](https://qiita-image-store.s3.amazonaws.com/0/67575/4619480f-b7a6-ab17-035f-9c90bb7f4c47.png)



###Learn how to add property to the element(ElementにPropertyを追加する方法)
Windows/uFrame DesignerからuFrame Designerウィンドウを開きましょう。
![uframe_open_graph_designer_instruction.png](https://qiita-image-store.s3.amazonaws.com/0/67575/45b68b67-fc7a-3a57-b3ee-34096f2f386a.png)

まず初めにMainMenuSystem Graphを開きます。開くためにタブをチェックしてみてください。
![uframe_graph_tabs.png](https://qiita-image-store.s3.amazonaws.com/0/67575/83b2654b-a1c5-2a41-7fa2-cf2854324312.png)
もしタブにMainMenuSystemがあったらそれをクリックしましょう。もしタブにMainMenuSystemがなければ、タブのちょい上にあるGraph選択のところからMainMenuSystemを選択しましょう。
![open_graph_example.png](https://qiita-image-store.s3.amazonaws.com/0/67575/b31ef12f-1190-b1d9-7974-22b53f3b62d0.png)

MainMenuSystemのGraphが開き、タブ一覧にMainMenuSystemタブがあることを確認できるかと思います。
![main_menu_graph_opened.png](https://qiita-image-store.s3.amazonaws.com/0/67575/839311a0-7773-d822-52fc-aba6127010d4.png)

他のGraphと同じようにMainMenuSystem GraphもNodeがあります。これらのNodeは様々な情報を表現しています。uFrame MVVMのNodeはNode自身の型を示す特別なSub Header(もしくはTag)を持っています(1)。今回のステップではLoginScreenと呼ばれるこのElement Nodeについて見ていきましょう。
![img_0000.png](https://qiita-image-store.s3.amazonaws.com/0/67575/38852ef7-bb51-106c-e8c0-93b9f88ed74e.png)

Element Nodeは、あなたのゲームのデータを管理するEntityを定義しています。例えばLoginScreenではUsernameとPasswardの情報を持っており、システムのログインに使います。
これらのノードは広げることでより詳しいデータを見ることができます。ノードについている矢印型のボタンをクリックすることでNodeを広げたり閉じたりすることができます。
![img_tut1_0000.png](https://qiita-image-store.s3.amazonaws.com/0/67575/3b4ed7b0-5e8e-24d7-32c2-fe4626bb3c9c.png)

LoginScreen Nodeを広げて、新しいプロパティを追加しましょう。これを行うためには、Propertiesと書かれたLabelの右側にある"+"ボタンをクリックする必要があります。
![img_0002.png](https://qiita-image-store.s3.amazonaws.com/0/67575/01019e5e-0566-4aeb-b846-068737716937.png)

Propertiesセクションに新しいNodeの子要素が作成されました。このような子要素は、左側に型を、右側に名前が書いてあります。
![img_0003.png](https://qiita-image-store.s3.amazonaws.com/0/67575/0237c8ca-b7d5-a84f-6d75-add519d7a263.png)

型(1)は、そのプロパティの型を表しています。プロパティ作成時には自動的にstring型が設定されています。名前(2)は、そのプロパティの名前を表しています。名前の初期値は"Properties"です。さて、ここで名前を変更してみましょう。新しいプロパティを追加するときはフィールドが自動的に編集モードになるのでそのまま名前を編集することができます。プロパティの名前を"ErrorMessage"にしましょう。Nodeの外側をクリックすることで編集を完了できます。もし後で同じPropertyをリネームしたくなったら再度編集モードにするために今の名前の部分をダブルクリックしてください。
さて、ここまでステップが終わればこんな感じのNodeになったでしょうか。
![img_0004.png](https://qiita-image-store.s3.amazonaws.com/0/67575/77c0ffe9-31a5-7b03-bcee-b41d779a4339.png)

このプロパティはstring型なので、特に変える必要はありません。しかし、プロパティの型を変えたいなら、型をクリックしてポップアップしたWindowから欲しい型を選択してください。
![img_0006.png](https://qiita-image-store.s3.amazonaws.com/0/67575/2ef00d10-2db6-4c36-a3ad-a0769ab80b25.png)

さて、ここまでで新しいプロパティをLoginScreenにElementとして追加することができました。

###Learn how to add binding to the view(Viewとバインディングする方法)
さて、MainMenuSystem Graphを開いていると思います。ではLoginScreen Element Nodeのヘッダーをダブルクリックしましょう。
![img_0007.png](https://qiita-image-store.s3.amazonaws.com/0/67575/95c47a13-f0b6-c2b1-d981-590fffc1068e.png)

これでこのNodeの詳細が見れるようになりました。MVVMは、**Model**,**View**,**ViewModel**の3つから成り立ちます。Element NodeはModelとViewModelを定義します。Viewに関しては別で管理するので注意してください。このサンプルでは、ViewはLoginScreenViewと書かれたView Nodeによって表現しています。
![img_0009.png](https://qiita-image-store.s3.amazonaws.com/0/67575/76851619-dbd2-d078-8bfd-00578545cb3f.png)

> 覚えておいてください。Element NodeはいくつでもView Nodeを持てます。

さて、LoginScreen Element Node(A)をLoginScreenView Nodeにつなげましょう。こうすることでLoginScreenView NodeがLoginScreenのdataを表現していることになります。また、LoginScreenView NodeがSubScreenView Nodeから繋がれているのもわかりますね(C)。より詳しいNode接続に関する説明についてはDocumentを読んでください。

このステップでは、ErrorMessagePropertyをText GUIに接続してみましょう。そのためには、LoginScreenView NodeのBindingsセクションの近くにあるプラスボタン(1)をクリックする必要があります。
![img_0010.png](https://qiita-image-store.s3.amazonaws.com/0/67575/603e4c81-4c48-3378-66ed-98d3ef7880bd.png)

Windowがポップアップされたでしょうか。このWindowにはバインディング可能なリストが表示されます。"ErrorMessage To Text"(1)を選択しましょう。
![img_0011.png](https://qiita-image-store.s3.amazonaws.com/0/67575/af26aa33-7693-1e76-cbf8-c03270eab94f.png)

選択できたらBindingsセクションのリストに表示されるはずです。
![img_0012.png](https://qiita-image-store.s3.amazonaws.com/0/67575/174f26ec-133f-63c4-f75f-ee5d5bb611f8.png)
これでLoginScreenView Nodeに新しいバインディングを追加することができました。

###Learn how to change logic in controllers and services(コントローラーとサービスを使ってロジックを変更する方法)
このステップでは少しだけコーディングします。Nodeに対する変更は全て終わったので、グラフをセーブとコンパイルしましょう。Window右上の"Save & Compile"ボタン(1)をクリックしてください。
![img_0013.png](https://qiita-image-store.s3.amazonaws.com/0/67575/bdd38524-4793-2c73-e822-fc53a96e4dc3.png)
グラフをセーブとコンパイルすることでグラフにセットしたアイテムをC#コードに変換できます。

コンパイルが終わったらコードを変更していきましょう。前回のステップでLoginScreenのErrorMessageプロパティをUIにバインディングしました。今回はもっと具体的にどうやってプロパティをセットするか教えたいと思います。

LoginScreen Element Nodeのヘッダーを右クリックしてください。コンテキストメニューが出てくるので"Open" ->"Designer Files" -> "MainMenuSystem"->"Controllers" ->"LoginScreenController.cs"を選択してください。
(ここは記事通りにはいかなかったのでちょいとメニューパスを変更しています。)
<img width="907" alt="20160818011556.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/534b8379-dd91-5043-63bc-93cd49761ee5.png">

これでIDEと関連ファイルが開かれると思います。それではコードを編集していきましょう。もし開かなかった場合はLoginScreenController.csスクリプトを検索して自分で開いてください。
Login関数に注目してください。この関数はログイン時に呼ばれます。中ではUserManagementServiceにUserNameとPasswordを渡してログイン処理を任せています。

```lang:LoginScreenControllerのLogin関数(編集前)
public override void Login(LoginScreenViewModel viewModel)
{
    base.Login(viewModel);
    /* Direct call to the service. */
    UserManagementService.AuthorizeLocalUser(viewModel.Username, viewModel.Password);
}
```

Login関数をこのように修正しましょう。

```lang:LoginScreenControllerのLogin関数(編集後)
public override void Login(LoginScreenViewModel viewModel)
{
    base.Login(viewModel);
    /* Direct call to the service. */
    UserManagementService.AuthorizeLocalUser(viewModel.Username, viewModel.Password);
    if(UserManagementService.LocalUser.AuthorizationState != AuthorizationState.Authorized){
        viewModel.ErrorMessage = "Failed to login! Incorrect username or password!";
    } else {
        viewModel.ErrorMessage = string.Empty;
    }
}
```

> 新しく追加したコードでは、ログイン申請後のステートを見てエラーがあれば関連したエラーメッセージを入力しています。

これでエラーメッセージをセットする修正が完了しました。

###Learn how to connect view with GUI(ViewをGUIとつなげる方法)
最後のステップでは、エラーメッセージを表示するためのMainMenuSceneにTextを作りましょう。
`Assets/ExampleProject/Scenes/MainMenuScene.unity`(1)を開いてください。
そしてHierarchyの`_MainMenuSceneRoot/MainMenuCanvas/LoginUI/LoginScreenPanel`(2)をみてください。
![img_0015.png](https://qiita-image-store.s3.amazonaws.com/0/67575/e8868bf1-9c85-b854-c756-4932e9dc32e5.png)
LoginScreenPanel GameObjectの子要素としてuGUIのTextを作成してください(1)。Textの名前やデザインは好きなように変更して問題ありません(2)。
![img_0016.png](https://qiita-image-store.s3.amazonaws.com/0/67575/f972d650-f77e-9fea-0464-4494f9b88e0a.png)

さて、次は、Hierarchyの`_MainMenuSceneRoot/MainMenuRoot/LoginScreen`を開き、LoginScreen GameObjectを選択してください。インスペクターに表示されているBindingセクションを開いてください(2)。ErrorMessageプロパティを設定しているところを見つけてください(3)。先ほど作成したText GameObjectをこのインプットフィールドにDrag & Dropしてください。
![img_0017.png](https://qiita-image-store.s3.amazonaws.com/0/67575/b013d7ca-b057-68b9-b0b8-5ea2e1444920.png)

###Perform final test
シーンを再生してみてください。不正なデータを入力してSign inボタンをクリックすると、エラーメッセージが見れるかと思います。



思いの外長かった・・・
引き続きuFrame勉強していきたい。