MarkLightの使い方を再学習するときに参照するまとめ
MarkLightとは?
UnityのUIをXUMLと呼ばれるマークアップLで記述できるアセット。
20161218現在 20$
www.marklightforunity.com
去年はMarkUXという名前でした。
UniRxとの繋ぎこみの話。
ykimisaki.hatenablog.jp
Documentation->Tutorialsオーバービュー
Examples and How To'sをちらっと
パラメータをエディタから探したいので、インテリセンスほしくなりますよね。
How to Get Intellisense in XUML
VisualStudioのスキーマフォルダにプロジェクト内にある.xsdファイルのアドレスを書き込む。
管理者権限でテキストエディタを開いて編集。
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas
に
<Schema targetNamespace="MarkLight" href="C:/
を書き込む。
つくったViewのxmlのルートを
<YourView xmlns="MarkLight">
こんな感じで
Getting Started
UIを作成する流れ
Sceneに空のGameObjectを作成->View Presenterをアタッチ
Viewファイル作成->using MarkLight.Views.UI して UIViewを継承
ViewModel(Viewと同名.cs)作成->
ViewのルートになるViewを作成->
ViewModel作成->using MarkLight して Viewを継承
View Presenter のインスペクターから ルートのViewを参照
スタイルをあてる
以下見出し的に紹介
View Action : イベントを指定したタグと結びつけられた名前のメソッドを呼び出す機能
Layout :
ViewSwitcher :
データバインディング : フィールドの値との TwoWay バインディングサポート
Animations : View上で名前で紐づけるアニメーション
SetValue() : UIの値を指定して変化させる
DependencyFields : SetValue()のエイリアス記法
View Models - Bringing Views to Life
クラス名<-->タグ名
フィールド名<-->パラメータ で紐づけ
SetValueメソッドで値を変更
型名の前に_をつけて宣言->ディペンダンシーフィールド
.Value で内部の値にアクセス(オブザーバーが効いてノティファイする)
.DirectValue で内部の値にアクセス(オブザーバーがスルーしてノティファイしない)
UIの子要素を宣言<-->タグ名
子要素UIの名前<-->Idパラメータ で紐づけ
もしくは <タグ名:クラス名 UI.フィールド="値"> の記法でダイレクト参照可
ViewAction型 UnityEvent(or カスタムメソッド名)
<クラス名 ViewActionの名前="値"> で紐づけ
メソッド名.Trigger()
メソッド名.Trigger(data) でインボーク
Textコンポーネントに紐づいた内部stringをディペンダンシーフィールドで表現
[Mapto("Textコンポーネントの名前.Text")]
public _string アクセス用の名前;
こう宣言するとUI.Text.Textにアクセス用の名前.Valueもしくはアクセス用の名前="値"でアクセスできる。
ChangeHandlerアトリビュートでフィールドが変更されたら呼び出すメソッドを定義できる。
MapToアトリビュートの第二パラメータで設定してもよい。
値のイニシャライズ専用の記法・メソッドがあるよ
データバインディング
記法は
ターゲットフィールド="{ソースフィールド}"
ソースフィールドをSetValueメソッド等で入れ替えると、自動的にターゲットフィールドが書き換わる。
ソースフィールドをディペンダンシーフィールドで定義すると(_stringのように型に_をつけて宣言)フィールド.Value=値 のように代入でSetValueと同じことができる
ネストしたパスに対して . でアクセスできる
フォーマットストリングバインディングやマルチフィールドバインディングをサポート
"{=ソースフィールド}"でワンウェイバインディング
"{#ソースフィールド}"でローカルバインディング
ListItemバインディング
<BindingExample> <List Items="{HighScores}"> <ListItem IsTemplate="True" Text="{#Item.Score}" /> </List> </BindingExample>
この例でListは、 ローカルバインディングされたアイテムのScoreフィールドを持つ ListItem を複数個保持する HighScoresオブジェクトをバインドしている。
ブーリアンのフィールドとバインディングした場合
IsChecked="{!ShieldActive}"
と値を反転して保持することができる
Resourceバインディング
ディクショナリーに対して、
"{@ディクショナリ名.キー}"もしくは"{@キー}"でバインディングできる
<Label Text="{!=#IsActive}" />
Negated One-way Local!
テーマとスタイルの作成
Themaタグ内で名前を指定してつくる
Thema内でstyleやidを指定しておくと使うときに適用された状態で呼び出せる
BasedOn=""でスタイルの上書きができる
見た目だけじゃなくふるまいを設定することもできる
テーマをひとつのシーン・ビューにいくつも読み込むことができる
Style="*"と書くと親のスタイルをインヘリト(継承)する
Working with List Data
List,DataGrid,ComboBox,TabPanelはリストに関係している。ひとまず基礎的なリストについて
Staticなリストはタグで簡単に作れる
Dynamicなリストは...
まず以下のモデルクラスを考えてみる
Highscore.cs
public class Highscore { public string Player; public int Score; }
自動変更通知リストとしてObservableList
上のモデルを含んだリストを見てみよう
DynamicListExample.cs
public class DynamicListExample : UIView { public ObservableList<Highscore> Highscores; public override void Initialize() { Highscores = new ObservableList<Highscore>(); Highscores.Add(new Highscore { Player = "PlayerA", Score = 100 }); Highscores.Add(new Highscore { Player = "PlayerB", Score = 750 }); Highscores.Add(new Highscore { Player = "PlayerC", Score = 9000 }); Highscores.Add(new Highscore { Player = "PlayerD", Score = 9000 }); } }
Viewにバインドする
DynamicListExample.xml
<DynamicListExample> <List Items="{Highscores}" Width="200"> <ListItem IsTemplate="True" Text="{#Item.Player} {#Item.Score}" /> </List> </DynamicListExample>
三つの重要なポイントがある
- <List Items="{Highscores}" /> オブザーバブルリストとバインドしたリストを宣言
- <ListItem IsTemplate="True" ... /> テンプレートを使うことを宣言
- <ListItem IsTemplate="True" Text="{#Item.Player} {#Item.Score}" /> 最後にitem template とItemDataをバインドする
見た目を整える
DynamicListExample.xml
<DynamicListExample> <List Items="{Highscores}" width="250"> <ListItem IsTemplate="True"> <Region Margin="10"> <Label Text="{#Item.Player}" Alignment="Left" FontColor="Black" FontSize="22" AdjustToText="Width"></Label> <Label Text="{#Item.Score}" Alignment="Right" FontColor="Black" AdjustToText="Widht"></Label> </Region> </ListItem> </List> </DynamicListExample>
xmlを書くときにEMMETを使ったので備忘
上のxmlをつくるときはCustom attribute の記法を使う
td[rowspan=2 colspan=3 title] <td rowspan="2" colspan="3" title=""></td>
DynamicListExample>List[Items={Highscores} width=250]>ListItem[IsTemplate=True]>Region[Margin=10]>Label[Text={#Item.Player} Alignment=Left FontColor=Black FontSize=22 AdjustToText=Width]+Label[Text={#Item.Score} Alignment=Right FontColor=Black AdjustToText=Widht]
以上を打ち込んで Ctrl + E(VScodeの場合はTAB)
itemの追加と削除
//インデックスによる削除 Highscores.RemoveAt(0); //リファレンスによる削除 var item = Highscores.Find(x => x.Player == "PlayerB"); Highscores.Remove(item); //itemの追加 Highscores.Add(new Highscore { Player = "Player", Score = 0 }); //インデックスによる追加 Highscores.Insert(0, new Highscore { Player = "Player", Score = 0 });
itemのアップデート(変更通知)
例えば、最高得点が更新されました、といったシナリオ
//Update Items public void UpdateScores() { //scenario#1 - アイテムによってプレイヤー名を更新する var item = Highscores[0]; item.Player = "New Name"; Highscores.ItemModified(item, "Player"); //senario#4 - すべてのリストアイテムのすべてのフィールドを更新 Highscores.ItemModified(); }
ひとまず備忘録として残します