RE:ADVスマートフォン用の表示で見るRE:ADVUnityでADVを作るブログこの広告は、90日以上更新していないブログに表示しています。UnityMarkLightとは?UnityのUIをXUMLと呼ばれるマークアップLで記述できるアセット。20$www.marklightforunity.com去年はMarkUXという名前でした。UniRxとの繋ぎこみの話。To'sをちらっとパラメータをエディタから探したいので、インテリセンスほしくなりますよね。XUMLVisualStudioのスキーマフォルダにプロジェクト内にある.xsdファイルのアドレスを書き込む。管理者権限でテキストエディタを開いて編集。href="C://Assets/MarkLight/Views/Schemas/MarkLight.xsd"/>を書き込む。アクセス用の名前;こう宣言するとUI.Text.Textにアクセス用の名前.Valueもしくはアクセス用の名前="値"でアクセスできる。ChangeHandlerアトリビュートでフィールドが変更されたら呼び出すメソッドを定義できる。MapToアトリビュートの第二パラメータで設定してもよい。値のイニシャライズ専用の記法・メソッドがあるよデータバインディング記法はターゲットフィールド="{ソースフィールド}"ソースフィールドをSetValueメソッド等で入れ替えると、自動的にターゲットフィールドが書き換わる。HighScoresオブジェクトをバインドしている。ブーリアンのフィールドとバインディングした場合IsChecked="{!ShieldActive}"と値を反転して保持することができるResourceバインディングディクショナリーに対して、"{@ディクショナリ名.キー}"もしくは"{@キー}"でバインディングできる最後にバインディングチートシートがついてます。DataList,DataGrid,ComboBox,TabPanelはリストに関係している。uGUIVectrosityという線を引くアセットを購入しました。magicbullet.hatenablog.jpbefool.co.jpシルバー事件リマスター版が出たのを機にプレイ動画を一気見したせいで、フィルムウィンドウと呼ばれていたあのシステムが気になりだしたのです。このゲームで<ウィンドウ>と呼ばれるものは線で演出されています。動きや、トランジションも線で視線を誘導します。今見返してみると同期・非同期が計算されて配置されていて、作劇法・ノベルゲーのシステムとして興味深いのはもちろん、プログラムの題材としてもおもしろいと感じました。線を引けるようになったのはいいのですが、しばらくいじっているとuGUIと連携できれば様々な問題が解決することに気づきます。LineとMonoBehaviourとの連携です。これは言い換えるとGameObjectとの連携ということになります。UnityはGameObject-MonoBehaviourを基点にAPIを組み上げている側面があり、これと連携することで画面構築上(ググラビリティ上?)相当な恩恵を得ることができます。(気づくのにけっこう時間がかかった...)考えていると、Panelの外枠に線を引ければそれだけでもいろいろできるようになることに気づきました。(っていうかPanelがUI>>Imageの絵なしバージョンってことさえこのとき知ったのですが)オブジェクトのコピーが簡単にできるので、同じ動きをするオブジェクトがあると役割を変えて重ね掛けができるんですね。ここで立ちはだかったのが、RectTransformです。UnityのUIを考える人全員の前に立ちはだかる壁になるのではないか。思うくらい強かったです。そもそもインスペクターウィンドウに表示されているものの意味がわからないじゃないですか。いや、感覚的にはアンカーもピボットもなんとなくはわかりますよ。それらのエディタUIが隠している計算がさっぱりわからない。Script的に公開されているプロパティも意味がわからない...。ググるしかありません。Nagaminewww.slideshare.netとくに今回は二つ目のスライドに助けられました。(読んでも意味がわからなくて、出てくるプロパティを片っ端からDebug.Log()したのは内緒だ)結論を述べると、親のCanvas下に作られたPanelのRectTransform、この矩形の角の四つの頂点をスクリプトから指定するには(このスクリプトをコンポーネントとしてPanel自身にアタッチするとして)、以下のように書きます。offsetMin.y);}}これが...こう!どこかの一辺だけに線を引くとかも選択的にできるようになりました。08:55【Unity】RectTransformの外枠に沿って線を引く!【uGUI】Tweet広告を非表示にするもっと読むコメントを書く2016-05-05やっぱり入力補完<インテリセンス>って最高なのではティラノスクリプト(tyranoscript)の入力補完についてです。できたので(情報量が多い...vscodeはまだできたてなので)そっちで作りこんでいこうと思います。入力補完のない世界って、本当は名前のない世界で暫定的な名前を*覚えられる*能力者にちょっと有利だと思うんです。規約で縛るのも、本当は名前なんてないものを「とりあえずこう呼ぼうよ」って決めたことにして*本当は名前のないものたち*を名付けているんだけど、そういうのが苦手(記憶力がない)な人に厳しい世界です。VisualStudio2013を触って衝撃的だったのは言語世界のツリーを別に人間が覚えなくてもよくない?っていう提案がすごくあって、それで世界に入れたのが大きかったと思います。一度入ってしまうとキャラ立ちして文字列も覚えられますしね。学習の補助をコンピュータがしているっていう当たり前なんだけど、まだ受け入れられてない世界観があります。当時のことがおぼろげですが、吉里吉里っていうゲームエンジンにはすばらしいエディタが開発されていて、人間の入力を助けていました。今、tyranoriderというデバッグ・入力補助ツールが開発されていますが、少し似ています。DSLの扱い方って難しくて、webの方ではだいぶヘイトを稼いでいるようです。(次々にいろいろ出てくるからね...)まあ、そこらへん乗り切るのに、入力補完がほしいと思ったのでちょっとやってみたっていう記事です。調べていくと、textmateっていうxmlのファイルがあるとカラライズ(色付け)ができるってわかってきます。拡張子は.tmLanguageです。vscodeの場合、そのファイルをYeomenなるもののコマンドを叩くと組み込まれるらしいです。code.visualstudio.comExtensionsのラングイッチサポートっていうそれらしいやつがそれだろうなと思いました。tmLanguageファイルをつくらなきゃダメらしい。いうわけでそっち方向にググりなおすと、この二つの記事にそのための知識がまとまっているとわかりました。qiita.comqiita.comさっぱりわかりませんでした。入門的な記事を探すとこんな記事が。qiita.comオレオレ記法をtextファイルに適用して、色づけしてみよう!っていう素晴らしいチュートリアルです。これを写経して、やっと意味が分かりました。tmLanguageファイルを編集するには、SublimeTextがよさそう、ということ。何はともあれパッケージコントロールでAAAPackageDevパッケージをインストールしなきゃいけないってことです。※AAAPackageDevパッケージはPackageDevパッケージに改名していました。慣れてない人間にxml形式のファイルを直書きするのはつらすぎます。pythonさんに(裏で)働いてもらいましょう。あと、上の解説ではjsonで書いていますが、jsonのエスケープをいきなり書くとたいてい動きません(僕は)なのでYAMLで書く下の例がサイコーということになります。どっちで書いてもPackageDevがtmLanguage形式に変換してくれます(F7キーで)。Documentationこういう英語のサイトの例も見ながらやります。引数を書きたいってときにネストするので、その書き方を見る必要があります。ところでどんな文字を色づけするか決めるって感じです。文字で囲うってことをしています。正規表現でマッチしたところが色づくとわかり、いったん白目になりますが、1日くらい勉強してなんとなくわかったら書きます。正規表現は三つの基本演算がある、ということを意識したら少し入れました(入門的な)。繰り返しこいつらです。いう本の1章にまとまってます。1章でキャプチャまで網羅してるのでとりあえず1章だけ読みます。Packages...>でエクスプローラが開くので、その中のUserフォルダに作ったファイル.YAML-tmlanguageと生成した.tmLanguageファイルがあると思います。うまくいっていれば新規ファイルを作成、言語をUser><拡張子の前に指定した名前>にすると色付けができているはずです!...でもこれってインテリセンスじゃないよね?そこで気づくのが.sublime-completionsなるものです。機械的な解釈をしていないので、インテリセンスという名前じゃなかったのかもしれませんが、疑似的にそういう風に動くようにしたい。そこでks.sublime-completionsを作ってさっきのUserフォルダに保存。先人の例をなんとなく改変していきます。タグ一文字なら登録したら終わりですが、パラメータがあるタグをどうやって登録するか。こんな感じになりました。},↑これもエスケープまわりですぐ動かなくなります。セーブするだけで反映されるので、トライアンドエラーが素晴らしく速くて、なんとか正解っぽくなりました。番号で指定している文字列(ここではパラメータval)にTabキーで一発で飛ぶので、動作的には完璧感しかありません。やった!狙った補完と色付けができたー!と思いました。コードヒントが出ない!!入力を途中までやっていると「あなたが探しているのはこれじゃない?」ってエディタがサジェストしてくれるあれです!あれがなかったら、こんなものなんの意味もありません。エディタは初めから狙った文字列を覚えている能力者のための道具でしかなく、プログラムの世界は僕のようにすべてを曖昧にしか記憶していない人間にはとうてい踏み入れられない砂漠でしかなかったのです。コードヒントでググれどもみんなメジャーな言語のコードヒントの情報しかググっていないので、独自のコードヒント出力法なんてさっぱりヒットしません。いうわけでふて寝してからもう一度基本に返って見直していると、最初にどっちでもいいよって感じで書いてあった設定回りのことが気になりました。[ks]このスコープネイムscopeNameのところです。マークアップならtext、プログラムソースならsourceって指定してね、って言われてた気がします。そこでsource.ksに変更して、もう一度コンバート(トランスパイル?)をかけます。すると...?サジェストが出たぁー!!選択すると?ちゃんと入力されています!パラメータも初めに入れておいたものが書式と一緒に出るのでなんとなく何をしたらいいかわかります。登録時に名前を変えておいて、自分用に最適化されたパラメータのサジェストとかも作ることができますね。※そういうのをスニペットというらしいです。(ちなみに上の例だと一つ目の引数storage=valは構文的にvalが""でくくられてないといけません。=のカラライズがうまくいっていません。それも意図通りの挙動です)砂漠ではとりあえず自分の通る道だけ覚えるという戦術で挑みたいと思います。そのための下地についての記事でした。整形後こちらのテキストをfirst.ksに張り付けると動作します。;コメントアウト*startTyranoscriptの変数では、オブジェクトリテラルと配列リテラルを使うことができます![l][r]以下をiscript/endscriptタグを用いて入力します。[l][r]([]は半角で読み替えてね。_line:[musashino-line","yamanote-line"]},[l][r]placeC:[{name:"nihonbashi"},{reiki:90},[r]{item:"master-key"}]}[l][r];実際にオブジェクトを設定しているところ[iscript]f.ppp={placeA:{name:"shibuya",reiki:100,item:"room-card",line:["metro-ginza","metro-hanzomon"]},placeB:{name:"akihabara",reiki:120,item:"radio",line:["musashino-line","yamanote-line"]},placeC:[{name:"nihonbashi"},{reiki:90},{item:"master-key"}]}[endscript][cm]では設定したオブジェクトにアクセスしてみます。exp="f.ppp.placeC[1].reiki"][r]オブジェクトの配列にアクセスすることもできる。[r](そのあとオブジェクトの名前を指定することでプロパティを得ています)。[r][l][cm]表示はこんな感じになります。exp="f.ppp.placeC[1].reiki"][r]この両方をペアで覚えておくと便利です。uGUIMarkUXはXMLとC#のview-modelでGUIを構築するUnityのアセット。Viewを日本語訳したのでメモとして残します。Viewビューの解剖学Introductionこのチュートリアルはアドバンストなビューを作るためにあなたたちが知るべきことを見ていく。通して見終わったとき、あなたはMarkUXのAPIをフルに活用できるようになっているだろう。Hierarchyビューの構築手続きを述べる前に、インポートもしくはプロセスが走ったときにシステムがビューをどのように表現するのか簡単に述べておこう。GameObjects)に変換され、シーンキャンバスのLayoutRoot以下にビジュアルヒエラルキーとして表示される。/></Group></MainMenu>以下のようなビジュアルヒエラルキーとなる。LightCanvas└LayoutRoot└MainMenu└Group├Button├Label└ContentContainer├Button├Label└ContentContainer└Button├Label└ContentContainerEventSystemビューモデル(View-Models)はコンポーネントとしてオブジェクトにaddされる。DeclarationViewクラスを継承するか、そのサブクラスはビューモデルクラスとして宣言される。このクラスの名前はXML上で参照しているViewの名前となる。View上のようにビューモデルの宣言時にアトリビュートによって情報を付与することができる。Attribute/Description[InternalView]このアトリビュートが付与されたビューモデルコンポーネントを持つビューは、Mainビューとして使えなくなり、ビュープレゼンターのドロップダウンリスト上から隠される。[AddComponent(type)]ビューオブジェクトが作成された時に(type)で指定されたコンポーネントを付与することを示す。[RemoveComponent(type)]ビューオブジェクトが作成された時に(type)で指定されたコンポーネントをリムーブすることを示す。[CreateView(type)](type)に基づくほかのビューを動的に作成することを示す。(type)がテンプレートとなる。そのテンプレートが動的にインスタンス化される。Declarationビューフィールドはビューモデル上のクラスに宣言される。この名前がViewXMLからフィールドを参照するときに使う名前となる。ContentAlignmentSet;ビューモデルクラスの宣言のように、フィールド宣言時にもいくつかのアトリビュートを使うことができる。Attribute/Description[NotSetFromXml]このフィールドがXMLからセットすることを許していないことを示す。[ChageHandler(name)]このフィールドがチェンジハンドラを持つことを示す。そのパラメータの名前はビューモデルにあるチェンジハンドラメソッドのものになる。[ValueConverter]デフォルトバリューコンバータがこのフィールドを用いたものに上書きされることを示す。これらのアトリビュートの効果を知るには、ビューフィールドのViewConvertersとChangeHandlersという二つのコンセプトに注目する必要がある。ビューの改装のために有用であろうチェンジハンドラから見ていこう。Handlersチェンジハンドラはビューが変更されたときに呼び出されるビューモデル内のメソッドだ。スタンダードなビューは三つのチェンジハンドラ──アップデートレイアウト、アップデートレイアウツ、アップデートビヘイバー──を持つことができる。UpdateBehavior()UpdateLayoutそのビューのレイアウトが変更されたときに(そのクラス内の)どのフィールドにおいても呼び出すことができる:Width,Height,Margin,Alignment,Offset,そして、OffsetParentUpdateLayoutsペアレントのどこかでレイアウト変更があった場合でも上記UpdateLayoutが呼び出される。UpdateBehaviourAlpha,BackgroundColor,etcの、見た目の変更(ただし、レイアウトの変更でない!)があった場合に呼び出される。これらのフィールドの変化に対応したメソッドはビューモデルでオーバーライド可能だ。このチェンジハンドラアトリビュートを使うことによってカスタムフィールドにチェンジハンドラを適用することが可能になる。ビューモデルでのチェンジハンドラの使用例を示す。behavior//重要。デフォルトレイアウトビヘイバーを上書きしたくない場合は、base.UpdateLayoutを呼び出すこと。base.UpdateLayout();}気をつけるのは、もしアップデートレイアウツ("s"がついている方)を付け加えようとした場合でも、UpdataLayoutの方を上書きするということだ。UpdateLayoutはUpdateLayoutsによっても引き起こされるからだ。(その場合でもUpdateLayoutsを上書きする必要はない。)デフォルトチェンジハンドラはもちろん使えるし、望むならどんなメソッドでもチェンジハンドラとして用いることができる。Valuesフィールド値のセットチェンジハンドラの設定をするためには、特別なジェネリックメソッドのSetValue()を使う必要がある。Orientation.Horizontal);もし、インターナルな値の変更を行いチェンジハンドラによるトリガーを発動したくない場合は、通常行うように値をセットすればいい。Convertersバリューコンバータは、異なったtype間のコンバートを行う。ContentAlilgnment="Top">string型をviewフィールドの値に変換するために、システムはValueConvertersを使っている。ValueConvertersはベースクラスにValueConverterを持ったクラス群だ。context){//カラー型への変換}}上記のコードはカラー型で構成されたColorValueConverterをつくる。システムがカラー型のフィールドに出会った場合、自動的に値のコンバージョン・変換にColorValueConverterを用いる。スタンダードバリュー(標準型)に対するバリューコンバージョン(型変換)を用意する。bool,int,float,ElementSize,Vector3,Sprite,Font,Margin,Orientation,Color,Alignment,etc.もしあなたが新しいviewのためのフィールド型(:一番多い例はenum(列挙型)だろう。)を設定した場合のみ、そのカスタムバリューに対するコンバーターを用意すればいい。AlignmentValueConverterがどのように実装されているか、例を示しておく。XMLのビューを参照しているかもしれない。参照したいXML上のビューにIdをつけるだけでそれを実現することができる。/></Group></CustomView>参照したいviewと同じ名前、同じ型のクラスフィールドを設定しよう。objectを参照することもできるだろう。Set-fieldsSet-fieldsは値がset済みかどうか指し示すことに使われる特別なbooleanフィールドだ。(プログラマティカリに、もしくはXMLで)値をセットした(はずの時に)正しいロジックでプログラムが動いているか確かめるのに有用だ。Set-fieldはあなたがトラック(追跡)したいと思うフィールド名のポストフィックス(語尾)にSetをつけて使う。ContentAlignmentSet;このときフィールドContentAlignmentSetは、ContentAlignmentに値がセットされていたときのみTrueを返す。追加のロジックをバインドするときに使う。ビューアクションはクラス内でViewAction型のフィールドとして宣言される。このクラスフィールドは、参照するXML内のアクションと同名にする。MyCustomAction;XMLで参照されるアクションを定義しよう。/></AnothorView>このアクションをトリガーするためにメソッドを呼び出す。Handlersビューアクションハンドラはアクションがトリガされたときに呼び出されるメソッドだ。アクションハンドラは呼び出されたときに用いる追加パラメータを持つことができる。Actions以下のような名前に設定したアクションを、ユニティのイベントシステムからトリガーさせることができるBeginDragCancelDeselectDragDropEndDragInitializePotentialDragMoveClickPointerClickMouseClickPointerDownMouseDownPointerEnterMouseEnterPointerExitMouseExitPointerUpMouseUpScrollSelectSubmitUpdateSelectedE.g.(例えば)あなたがクリックアクションをビューに追加したければ、単にClickとアクションの名前を書くだけで自動的にユーザーがクリックしたときにトリガーされる。Viewsもし独自のViewが必要であれば、コンテントとしてContentViewを継承するだけでいい。ContentViewビューXML上でとビューを指定してそれをコントロールすることができる。/></Region></MyCustomContentView>どんなコンテントでもコンテントコンテナをチルドレンとしてビューに追加することができる。コンテナそれ自体を追加分に含めたくない場合は、IncludeContainerInContentフィールドをFalseにセットすればいい。XML気づいたかもしれないが、どのスタンダードなビューもXMLファイルと分かれていない。XMLがview-modelに組み込まれているのがその理由だ。これはビューのディストリビュートや別ファイルでビューを持ちたくないときに役立つかもしれない。(どんな方法でもビューのシェアをしてもらえるとありがたい。)XMLの埋め込みには単にGetEmbeddedXML()をオーバーライドすればいい。/></Frame>";}すでにビューのコンポーネント、主要な構成要素については解説した。アドバンスドビュー作成のための情報はとりあえず十分だろう。TyranoScriptv342です。javascriptよくわかってないマンがさらっと読んだだけなので、間違ってる可能性ファイル名はlib.js(function($){});プラグインは囲うんだって$.setBaseURLパスからURLを取得$.isHTTP最初の四文字を調べてHTTPかどうかを返す$.play_audioオーディオ再生中かどうか$.getViewPort表示画面の高さと幅を返す$.escapeHTML=function(val,replace_str){}valで指定したdivタグを作成する。それが""(文字列なし、boolean:false)ならreplace_strにする。imageが含まれていた場合、それを適応する)$.convertColor=function(val){}0xが含まれていたら#に変換して返す$.convertBold=function(flag){}flagがtrueなら"bold"を、そうでないなら""を返す$.send=function(url,obj,call_back){}//game.current_story_file=story_file;ajaxする。読み終わったので、次は標準のプラグイン(kag)を読んでみたいと思います。01:28TyranoScriptのjQuery拡張部分のメソッドを書き出してみたTweet広告を非表示にするもっと読むコメントを書く2014-12-27コンソールアプリケーションで学ぶReactiveExtensionの仕組み(チュートリアル作ったよ)なんとなくRxよさそうだな、もっと勉強したい!という欲が高まってきたのですが、Unityをいきなり絡めると決まりごとが増えるので(MonoBehaviourのUpdate()の仕組みとかCoroutioneとか)、単純さを前面に押し出した勉強法を探していました。単純!基本!といえばコンソールアプリケーションです。僕も2014年からC#勉強し始め組として、VisualStudioを使ったコンソールアプリケーションでの勉強法はプログラム習得にとても有効だったと思っています。ReactiveExtension(Rx)を学ぶのにも、大量のコンソールアプリケーションのサンプルがあればいいなぁと思いました。それで探してみると、ちょうどよさそうなのがありました。このサイトのサンプルをもとにチュートリアルを作ってみたいと思います。Contentsから、サンプルコードを選んでいきます。IObservable<T>(訳:IObservable<T>のバックエンドとしてのSubject<T>)をやってみたいと思います。このSubject<T>がすごく便利で、今後頻出することが予想されます。(Subject<T>は一言で言うと、IObserver<T>とIObservable<T>どちらも実装したクラス)元のコードはこれ↓orderクラスはプライベートなフィールド_paidDateを持ちます。(DateTime?はヌル許容型)次にプライベートなストリーム、order型のサブジェクト_paidSubjをnew演算子で作ります。その_paidSubjをAsObservable()して返すゲッターを設定。(これで他のクラスに公開されます)メソッドMarkPaid()は_paidDateを引数から設定し、_paidSubjストリームに自分自身(order)をOnNext()しています。Subject<T>ストリームはIObserver<T>を実装しているのでOnNext()が可能なんですね。OnNext()することでストリームに値が流れます。ここでのポイントは流れている値の型が<order>ということです。これについては後ほどいじってみたいと思います。VisualStudioを立ち上げ、C#の新しいプロジェクトからコンソールアプリケーションを作成します。ReactiveExtension(Rx)を参照するライブラリに追加しなければなりません、ので、NuGetを使います。ソリューション・エクスプローラーの[ConsoleApprlication57]を右クリック。Packages...]を選択します。入れてやると一番上に目的のライブラリが出てきますので、インストールします。途中で何か聞かれたらacceptしてずんずん進んでください。名前空間に追加することでReactiveExtensionが使えるようになりました。サンプルコードの通り、打ち込んでいきます。これを実行すると...無事動きました。Main関数の中で、新しいorderオブジェクトを作成し、Paidストリームが値を受け取ったときの挙動をSubscribe()メソッド(内のラムダ式)で定義しています。サンプルでは、Paidというストリング型の値を表示していますね。最後にMarkPaid()メソッドを実行して値を流しています。ここでふと思うのは、<order>型のオブジェクトを流しているのに、出力は関係ないストリングっていうのはあまりおもしろくないな、ということです。MarkPaid()メソッドはDateTimeを引数に持っているので、その値を出力できないか?というわけでやってみました。