【Unity】OnPostProcessAllAssetsを使う時に特定の方法で無限ループする

 

OnPostProcessAllAssetsについて

docs.unity3d.com

 

このクラスを継承したEditorクラスは、OnPostProcessAllAssetsメソッドを定義することでアセットインポート時に処理をフックすることができる。

 

ScriptableObjectやなんやに自動登録したり、asset判別して何かする時によく使う。

 

無限ループする原因

 

  1. OnPostProcessAllAssetsを定義したクラスが2つ以上ある
  2. そのどちらも、処理の中でAssetDataBase.StartAssetEditing()とAssetDataBase.StopAssetEditing()を呼んでいる。
  3. どちらもAssetDataBase.Refresh()を呼んでいる。

 

以上です。

 

docs.unity3d.com

 

 

アセットインポート時に、さらにアセットをインポートする処理を書いてしまうとOnPostProcessAllAssetsをお互いに呼び合ってしまうので無限ループするっぽいです。

 

 

回避方法

 

  1. OnPostProcessAllAssetsは引数に変更されたアセットのパスが入っているので、パスを使用し処理を行うべきか否かを判別する
  2. OnPostProcessAllAssetsを受け取るルートクラスを作成し、個別に受け取らない

 

 

最後に

 

回避はこれで可能、原因も多分あってる。

ただどうにも釈然としないので、何かピンと来た方Twitterまでぜひご連絡ください。

 

【Unity】Timelineで使用するPlayableAssetとPlayableBehaviourを参照を追加しながら作成するエディタ拡張

 

リポジトリ

github.com

 

ここにプロジェクトとUnitypackageがあがってるのでダウンロードなりcloneなりをどうぞ

 

 

使い方

 

メニューに表示されているPhantomIsland -> Windowからエディタを開いてください。

 

 

設定できる項目は

 

  • 使用するnamespace
  • 変数の型、変数名、参照タイプ

です

 

参照タイプはシーン上のオブジェクトはExposedReferenceを選択してください。

大体ExposedReferenceだと思います、多分・・・。

 

CreateScriptボタンを押すと、保存先と名前を指定するウィンドウが出るので設定して保存して下さい。

 

保存した名前の末尾に~Assetと~Behaviourという名前が付くので、~Playableという名前がよいかも。

 

保存すると、設定した参照がすべて記入されており、PlayableAssetはいじる必要がなく、基本的にPlayableBehaviourにロジックを記述するだけでよくなっています。

 

最後に

 

まだまだTimelineは進化しそうなので、情報を追っていきますぞ。

【C#】NSubstituteを使用してクラスをモックとして偽装する

 

NSubstituteとは?

 

定義されたinterfaceを使用して、クラスの振る舞いをモックとして定義することが出来るライブラリ

 

interfaceに定義されているフィールドやメソッドの返す値や動作を一つずつ定義できるので、テストしたいクラスに渡すデータなどの偽装が可能

 

とにかく非常に便利で、使いやすく有用

 

入手はこちら

github.com

 

 

Unityで使用する際はUnity Test Tools を入手して、Pluginsの中にdllを入れると動作する

 

https://www.assetstore.unity3d.com/jp/#!/content/13802

 

基本的に実機動作はしません、UnityならEditor上のみで使用するようにしてください 

 

簡単な使い方

 

クラスとフィールド、メソッドの動作を偽装した例

 

gist.github.com

 

 

割と簡単に定義できる

 

 

ちょっとした小技

 

メソッドの中で自身のフィールドを変更したい時などは、一度データをキャッシュするとよい

 

gist.github.com

 

直接フィールドを書き換えることはできないので、気をつけよう

 

 

ある特定の機能だけ動作させたいけどデータがないよ〜という時はガンガン使っていこう

ブログ名とかを変えました。

 

 

ブログ名とか、中のデザインを一部変えました。

 

開発とかメモ -> かせの開発とかメモ。 -> かせノート。 <- New!

 

書くことはほとんど変わらないと思いますので、今後ともご愛読くだされば幸いでございます。

 

よろしくお願いします。

【プログラミング】MVC,MVPを理解するためのレイヤーアーキテクチャ

 

少しだけ長いので、根気を持ってお読みください。

 

レイヤーアーキテクチャについて

 

言葉で表現すると

  • 個々のオブジェクトの設計に依存しない、概念的な部分の設計思想
  • 各機能の「置き場所」の定め方
  • あるいは、各機能の依存先を決める手段
  • 責務を明確化する思想

 

この記事を読んでいるということは、MVPやMVCについては聞いたことがある、実践したことがある人は多そう

前提知識としてあると理解しやすい、かも

 

 

詳しく説明してくれている記事がありました

 

qiita.com

 

引用

"レイヤアーキテクチャというのはアプリケーションを責務に応じたいくつかの層としてとらえる設計手法のことです。"

 

表面的にはまさにこの通りですが、層という概念に当てはめてしまうのはいささか語弊があります

 

この記事のMVCの部分はすっ飛ばして(失礼ではありますが)レイヤーアーキテクチャの部分だけを読んでいただけると良いと思います

 

 

今回伝えたいことは、プレゼンテーション層、ドメイン層などで固定化されたレイヤーの話ではなく、必要な責務を考え、自身のアプリケーションに応じて必要なレイヤーを考え出すことをレイヤーアーキテクチャの知識として定義したいという話です

 

 

アーキテクチャの歴史

 

レイヤーアーキテクチャの理解のために、過去のアーキテクチャの歴史をまず振り返ってみます

 

オブジェクトアーキテクチャの歴史

 

いわゆる、個々の機能の設計です、大まかに3つの進化がありました

 

goto statement programming

goto文 - Wikipedia

 

プログラムの要所要所にラベルを定義し、goto文を使用して指定したラベルに飛ぶことで、ロジックを全て縦に記述しながらも強引にモジュール化を図るプログラミング手法です

 

あっちこっちに処理が飛び、人間の脳内キャッシュを膨大に使用するので今見ると非常にスパゲッティコードに見えるでしょう

 

www.linuxdigest.org

 

なぜgoto文が悪であるのかはこちらの記事を読むとわかりやすいと思います

 

 

 structured programming

構造化プログラミング - Wikipedia

 

構造化プログラミングのことです、かなり端折った説明をしますので本来の意味合いを知りたいのであれば書籍などを購入すると良いと思います

 

構造化プログラミングはgoto-lessとも呼ばれ、ロジックを上流(状態)、下流(処理)に分けることで上流の状態に応じた下流の処理を呼び出すという概念が生まれました

 

しかし、処理を分割すればするほど上流の状態が増えることになり、完全なロジックの分離はほとんど不可能でした

 

しかし、goto statementにはなかった、処理の記述に流れを作るという点において、近代のプログラミング思想の根底に関わっています

 

object oriented programming

オブジェクト指向プログラミング - Wikipedia

 

皆大好きオブジェクト指向です、もはや呪いと言っても過言ではなさそうです

 

カプセル化ポリモーフィズムなど様々な概念が存在しますが

 

データとロジックを一つのまとまりとして記述し、処理の関心を内側にのみ向け、処理に応じたメッセージを発行することで、他のオブジェクトの処理のトリガーとして影響を与えつつ、その影響に関心を持たない

 

という概念になるかと思います

 

これを端的に表したものがオブジェクトという言葉であり、またクラスという機能として表現されているものです

 

この概念を用いることで、structured programmingだけではなしえなかったロジックの完全な分離が可能になりました

 

 

オブジェクトアーキテクチャのまとめ

goto statement programmingで処理を記述するという行為を行い

structured programmingで処理の流れの概念ができ

object oriented programmingでロジックの分離を行った

 

 

しかし、これでは処理の置き場所はオブジェクトで定義できましたが、オブジェクトの置き場所が定義できていません

ここからはオブジェクトのまとまりをレイヤーとして定義するアーキテクチャについてです

 

 

多層アーキテクチャ

多層アーキテクチャ - Wikipedia

 

近代的な設計思想は多数ありますが、そこから多層アーキテクチャを抜粋します

 

 

独立したモジュールとして層を定義し、差し替え、機能改善などを容易にすることが可能な設計思想です

 

代表的なものとして三層アーキテクチャが存在します

 

 

三層アーキテクチャは、Webアプリケーションが

  • データベース
  • ミドルウェア(インターフェース)
  • ユーザー(ユーザー操作)

という要素で構成されるようになった際に提唱された概念です

 

 

データ、ロジック、プログラミング的な構成要素としては

の三種類が必要になります

 

データベース

 

データを保持、管理します

 

ビジネスロジック

 

ユーザー操作に応じた処理のロジック、及びデータベースの操作を記述し公開します

 

ユーザーインターフェース

 

ユーザーの操作を検知し、操作に応じた処理をビジネスロジックに問い合わせます

(APIを叩くということと同義です)

 

ビジネスロジックの結果を使用して自身を更新します

 

 

以上のように、各レイヤーに対して明確に責務が割り当てられており

また、依存関係が単方向になっています

 

ユーザーインターフェース -> ビジネスロジック

ビジネスロジック -> データベース

 

データベースは自身以外を知りませんし、ビジネスロジックはデータベース以外知りません

ユーザーインターフェースビジネスロジック以外知りません

 

 

単方向ですね

 

責務を明確化すると、その責務を果たすために必要な情報を持つレイヤーに対してのみ依存する形になるため、結果として関連するロジックを持つオブジェクトの凝集度が上がり、依存関係を簡潔に定義することができます

 

 

レイヤーアーキテクチャのおさらい

 

  • 個々のオブジェクトの設計に依存しない、概念的な部分の設計思想
  • 各機能の「置き場所」の定め方
  • あるいは、各機能の依存先を決める手段
  • 責務を明確化する思想

 

です

重要な部分は責務の明確化です

 

 

MVC,MVPとは一体なんなのか?

 

Model - View - Controller

 

Model - View - Presenter

 

さらにはMVVM,CleanArchitectureまで様々な概念が存在します

 

これらはすべて、レイヤーアーキテクチャに基づいた責務の割り当て方の一つの形です

 

一般的に普及していると思われるMVCの例

 

Modelの責務

  • データを管理する
  • データを更新するためのロジックを公開する
  • (必要であればサーバーと通信する)
  • データの更新を通知する

 

Viewの責務

  • ユーザー操作を提供する
  • Modelの通知、データを元に自身を公開する

 

Controllerの責務

  • ユーザー操作を監視する
  • 操作に対応したModelの更新ロジックを呼ぶ

 

 

こういった形で責務が割り振られています

 

MVPも同じく、責務が割り振られています、MVVMもCleanArchitectureも同じです

 

 

こういった責務を捉える力を持つことで、MVCやMVPなどの既存のレイヤーに縛られない責務の洗い出し、割り振りが可能になります

 

 

例.MVCを、サーバーとの通信部分を踏まえて責務の割り振りを改善する

 

一般的なMVCの責務は前述しましたが、Modelがサーバーと通信する場合、しない場合を踏まえて、サーバーと通信するという責務を切り出し、別のレイヤーとして定義します

 

名前はServiceレイヤーとし、SMVCと定義します

 

 

Serviceの責務

  • Modelを更新するためのロジックを公開する
  • Model更新のためのデータをサーバーから取得する

 

Modelの責務

  • データを管理する
  • データを更新するためのロジックを公開する
  • データ更新の際に必要であればServiceのロジックを呼ぶ
  • データの更新を通知する

 

Viewの責務

  • ユーザー操作を提供する
  • Modelの通知、データを元に自身を公開する

 

Controllerの責務

  • ユーザー操作を監視する
  • 操作に対応したModelの更新ロジックを呼ぶ

 

 

切り出しました

 

MVCにはないメリットとして

このServiceレイヤーはサーバー側にのみ依存し、またローカル用のモックと差し替えることでローカル環境での更新も可能になりました

結果、Modelはシンプルな記述のみになったと思います

 

他にもあるかもしれません 

 

 

こういった形で設計を改善することもできます、参考になったでしょうか

 

 

まとめ

 

責務を洗い出し、責務の一つ一つをオブジェクトの集合体となるレイヤーに割り振ることを

 

レイヤーアーキテクチャ

 

として定義し、広く理解され普及すると良いなと思います

 

 

知識の部分は厳密には間違いがあるかもしれませんが、伝えたいことが伝わっていれば幸いですね

 

【Unity】TestRunnerをbatchmodeで起動した際に謎xmlが吐き出されるバグ

 

解決策があれば教えてください

 

 

バージョン

Unity5.6.2f1

 

 

ソース

issuetracker.unity3d.com

 

 

やりたかったこと

Jenkins上でUnityTestRunnerをbatchmodeで起動して、吐き出されたxmlをNUnitPluginで解析

CI環境で自動テストを行いたかった

 

結果

上記Issueのためできなかった

xmlの吐き出される形式がTestSuiteのため、NUnitPluginがうまくパースしてくれない

 

結果、ビルドがコケる

 

Unityさんへ

早く治して・・・

 

【Unity】UniRxで独自オペレータを作る、Observableの拡張

UniRx

github.com

 

いつもお世話になっています。

 

オペレータとは

IObservable<T>の拡張メソッドとして用意されたストリームソースを加工するためのクラス

オペレータはIObservable<T>を継承しているので、メソッドチェーンすることができます

 

ざっくりふわふわとした説明は以上

 

作るもの

オペレータの作成のためにはまず2種類のクラスと拡張メソッドを定義する必要があります

 

具体的には

 

  • OperatorObservableBase<T>を継承したストリームをSubscribeするクラス
  • OperatorObserverBase<TSource,TResult>を継承したストリームを加工する処理を書くクラス
  • IObservable<T>をソースとして受け取り、作成したOperatorObservableBase継承クラスの中にソースを流し込んでnew()して返す拡張メソッド

 

です、最初は何言ってるかわからないと思います

 

適当に作っていきます

 

BossObservableをいうものを作ってみようと思います

原理の説明やこれなんのGenericやねんというのはまったく説明しません 

 

 

オペレータが作成された時(newされた時)に

「デキタヨ!」

オペレータの中を処理が通った時に

「トオッタヨ!」

オペレータの中をErrorが通った時に

「アワワワワワ」

ストリームがCompleteした時に

「ボクニマカセテ!」

 

を出力したいと思います、特に意図はありません。

 

まずはBossObservableを定義します

 

gist.github.com

 

これで定義できました。

基本的にObserverOperatorBaseを継承したクラスの

new()

OnNext()

OnError()

OnComplete()

にいろいろな処理を書くことができます

 

ストリーム中にインプットを止めたい・・・などはかなり多い拡張かと思います

 

 

次は拡張メソッドを定義します

 

gist.github.com

 

 

シンプルです、前回のオペレータをsourceとして引数で引っ張ってきて、newして返すだけです

途中の処理は重複回避やnullチェックですが、重複してもよければ省きましょう

 

以上でBossの定義ができました

 

 

これで全てのストリームに対して.Boss()を挟むことができます

やったぜ

 

 

最後に

UniRxに既に定義されているオペレータだけでも処理はできますが、やはり1つラップされた処理があると使う方は非常に楽です

 

書いていれば理解できてくると思うので、ぜひいろいろ試してみてください