やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

フォトグラメトリでバ美肉(1) 3DF Zephyr

たくさんの写真から3Dモデルを作り出すフォトグラメトリ(Photogrammetry)があれば、モデリングができなくても絵心がなくても、フィギュアからVRChatやVRM向けのアバターを作ってバ美肉*1できるのでは? ……などと甘い考えのもと、試してみた結果を晒します。

結論と注意事項

いきなりですが、結論として、2つの理由からフィギュアからフォトグラメトリしたモデルをアバターに使うことはないでしょう。理由は、クオリティ(コスト)の問題と、権利的なものです。

クオリティ(コスト)面

前提として、今回の作例は、かなり雑なライティング・雑な撮影・ろくにレタッチしない、という三重苦のもので、正直ソフトメーカーさんに申し訳ないレベルのものです。

少し頑張れば、背景オブジェクトやプロップ的なものには十分使えるものが私にも作れるとは思います。が、アバターとなるとさらにリギングして動かすための工数もかかるので、もう「素直にモデリングを頑張るべきでは」という気持ちになりました。

誤解してほしくないのは、フォトグラメトリがクオリティ低いのでないということです。今回くらい雑に作ってもこのレベルの成果物が得られるというのはすごいことなので。

権利面

フィギュアはほぼ間違いなく誰かの著作物です。使いかたによっては、単にキャラクターのIPだけでなく、そのフィギュアを作ったメーカーの権利をも侵害することになります。

特撮界隈では改造怪獣とか昔からあるわけですが*2、同じノリでフォトグラメトリで得たモデルを素体として改造してーというのも、イラストにおけるトレースと似たようなものですし、やはり避けるべきでしょう。

結論は結論として、以下、作例として進めていきます。

3DF Zephyr

3DF Zephyrにはいくつかエディションがありますが、Lite Steam Editionをサマーセールで購入しました。解析できる写真枚数に500枚という制限がありますが、建造物や空撮などしなければ十分でしょう。フィギュア程度なら、Free版の50枚でも十分なはず。

store.steampowered.com

チュートリアルやマニュアルはこちらに。

https://www.3dflow.net/technology/documents/3df-zephyr-tutorials/

バージョン4.009をインストール後、こちらのブログにある、座標系をY Upにする設定だけ行ないました。初期値については、Zephyr 4.xでは英単語になっていました。

manabuokajima.hatenablog.com

写真を撮る

写真は、フィギュアを台に固定して、その周囲を回りながら細かく撮影していきます*3。一般的な室内では足元に影ができてしまうため、曇天の屋外での撮影が良いようです。

Zephyrのマニュアルによると、撮影は以下の要件を満たすことが好ましいみたい。

  • ISO感度: 低め
  • 絞り: 高め (f/8 - F/16)。広い被写界深度が得られる
  • 焦点距離は固定
  • 各写真の間に重複があること (70-80%)
  • 各写真の角度をできるだけ保つ

本作例は、室内の蛍光灯ひとつの下という劣悪な環境で、iPhone Xで撮影しています。カメラアプリは"Adobe Lightroom CC"のマニュアルモードで、Sec: 1/10, ISO: 40, WB: 蛍光灯 の設定。

また、簡易なレフ板(段ボール板にアルミホイルを貼ったもの)を使用しましたが、フィギュアを丸テーブルに載せていることもあってあまり有効に使えていません。

低密度点群生成

3DF Zephyrを起動し、ワークフロー > 新規プロジェクト で写真を取り込み、低密度点群を生成します。デフォルト設定で2〜3分。

f:id:nowsprinting:20180924071720p:plain

下方にある茶色の点群はフィギュアを置いた丸テーブル、中央付近に、ほとんど見えませんがフィギュアがいます。上方に円形に散らばっている青い四角錐は写真の撮影位置を示しています。

この点群を生成したときの写真は94枚、うち63枚が有効でした。1/3ほどの無効写真はランダムに点在したのではなく、ダメな方向からの写真は複数枚まとめて無効となることが多いです*4*5。結果、その角度のディティールは大幅に損なわれます。

この段階で、周囲の不要な点群は処理対象から外すことができます。グレーの立方体が処理対象となる「境界ボックス」で、この外にある点群は無視されます。また、もっと柔軟に、不要な点群を選択して削除していくこともできます。

高密度点群生成

続いて、ワークフロー > 高密度点群生成 を実行します。デフォルト設定で10〜15分くらい。

f:id:nowsprinting:20180924073509p:plain

前掲の岡島さんブログによると、高密度点群の時点では何も触らないほうがいいようです。

メッシュ抽出

ワークフロー > メッシュ抽出。2〜3分。

f:id:nowsprinting:20180924074858p:plain

背景(部屋の壁や家具)が丸テーブルの周囲にバリ*6のようにメッシュ化されてしまったので、これを削除します。

f:id:nowsprinting:20180924075226p:plain

近づくとこんな感じ。うちに美少女フィギュアがなかったので、被写体には"美味しそうなイカ"フィギュアを使用ました。バーチャル美味しそうなイカ肉!(タイトル回収)

f:id:nowsprinting:20180924075244p:plain

この時点で、頂点: 39,084、三角ポリゴン: 77,823

これを削減します。手段はZephyr上でも複数、外部ツールもいくつかありますが、それらは改めて検証したいので、今回はZephyrのリトポロジーツールを使います。

ツール > メッシュフィルター > リトポロジー を、factor: 5.00、repert: 10 で適用*7

結果、頂点: 8,933、三角ポリゴン: 17,497 まで削減できました。VRChatアバターの制限が20,000ポリゴンなので、パスできるはず。

f:id:nowsprinting:20180924075910p:plain

見比べると、触手の先やえんぺらなどのエッジが欠けて(丸くなって)しまいましたが、今日のところはこのまま進みます。なお、テクスチャのぼやっとした感じは後工程でほぼ気にならなくなります。

ポリゴンメッシュはこんな感じ。

トポロジー

f:id:nowsprinting:20180924081136p:plain

トポロジー

f:id:nowsprinting:20180924081151p:plain

テクスチャ付メッシュ作成

ワークフロー > テクスチャ付メッシュ作成 でテクスチャが貼られます。本例では、最大テクスチャサイズ: 2048、最大数:1 としました。

f:id:nowsprinting:20180924082150p:plain

スケール/回転/平行移動

ツール > ワークスペース > オブジェクトのスケール/回転/平行移動 という機能があるのですが、スケールは単位が、平行移動(原点座標)は、そもそもの基準点がわからないため、Zephyrで調整するのはあきらめました*8

ここでは回転だけ行ない、Y+を上方向、Z+を正面方向に設定します。テーブルの面を使って、ツール > ワークスペース > 平面を選択して上向きベクトルを定義 で上方向を指定すると楽です。

テクスチャ付メッシュを出力

出力 > テクスチャ付メッシュを出力 で、.objもしくは.fbx*9ファイルにエクスポートします。

エクスポート時のオプションに"ローカル表示基準システム”(local rendering reference system)がありますが、これは、

  • off: ワークスペース上のスケールと座標がモデルに反映される。ただしスケールの単位が何かわからないし、原点がどこかもわからないので、人類にはコントロールは難しい
  • on: ワークスペースのスケールと座標が無視される。サイズはすごく大きい(xyz各100倍くらい)、座標はモデルの中心になる

3DF ZephyrのWebサイトには

if you are using geographical coordinates, you may need also to check “Local Rendering Reference System” as well.

とだけありました。空撮でないのでgeographicalな座標がないから上記の振る舞いになってる?のでしょうか。

リギングするならBlender等で調整しますし、今回はUnity直送ですがUnityで調整すればいいので*10、どちらでも構いません。

Unityにインポート

エクスポートしたfbxをUnityにドラッグ&ドロップ。試しにVRChatのHome Kitにある部屋に配置してみました。

f:id:nowsprinting:20180924082919p:plain

いかレスラーの身長を設定*11に忠実に242cmとしたのですが、胴が(頭足類なので頭部の上は胴です)天井を突き破ってしまいました。本編および本物のぬいぐるみ(着ぐるみ)を見た感じ、もう少し小さくていいような気がします。

なお、向かって左はスマートフォンアプリ"Qlone"で作ったモデル、右は野良犬祭2でDiGINELさんが持ち込んでいた撮影ブースで撮影してもらったリアルアバター(60,000ポリゴン・テクスチャ8192)。

Qloneについてはこちらを参照。

とりあえず今回はここまで。次回以降、リギングとかリトポロジーとかディライティングとかやっていく予定です。飽きなければ。

補足

以下、おまけ。

フィギュア撮影の難点

これまでに掲載したスクリーンショットからも、触手の間、下側、また足元などのクオリティが低いことが見て取れたはずです。これらは撮影環境の悪さが大きいのですが、フィギュア相手ではよほどライティングを頑張らないと足元の影の影響は残るでしょう。

今回はそれだけでなく、右後方はメッシュもテクスチャもおかしくなっていました。この方向からの有効な写真が無かったことが主な原因でしょう。

f:id:nowsprinting:20180924082938p:plain

またアオリ(ローアングル)で撮れていないため、下側のメッシュには穴が空いていたりします。

f:id:nowsprinting:20180924082948p:plain

上下逆にして撮ってみる

回避策として、被写体を上下逆に置いて撮影、フォトグラメトリ処理したモデルを結合させるのがいいのかな、と思っています。試しに撮ってみた例が以下。

f:id:nowsprinting:20180924083102p:plain

f:id:nowsprinting:20180924083119p:plain

吸盤のモールドまでバッチリですね。

なお、被写体を三脚の上に立てての撮影も試みましたが、いかと部屋の壁の色が近いこともあって、肝心の被写体が壁に溶け込んでしまいました。上例の丸テーブルのような拠り所も必要なのではないかと。

その他の作例

先日、小石川後楽園の円月橋を片面だけ撮影してきたものをSketchfabに上げています。片面だけなので少し角度を変えると破綻しますが。これで元写真67枚です。

参考

manabuokajima.hatenablog.com

*1:バーチャル美少女受肉の略。またたく間に広義から狭義までゆらぎのある言葉になったが、発祥についてはこちらの記事が詳しい https://www.vtuber-housou.com/babiniku/

*2:それが無ければジラースとかミレニアムファルコンとか存在しなかったわけですが…

*3:フィギュアを手に持ったり、台を回転させたりしての撮影したものは使えません。背景も含め特徴点を取るので、動かないことが要件なのです

*4:上のスクリーンショットでも、円形に並んでいる青い撮影点が二箇所途切れているのがわかるはず

*5:原因は恐らく、背景に特徴点が少なかったり、明度によるものだと思われます

*6:バリって英語のBurr、バリ取りはDeburringなんですね

*7:ちなみに[フィルターを適用]ボタンは編集対象のメッシュを上書き、[フィルタを有効にする]ボタンはコピーを作って適用してくれます。わかりにくい!

*8:スケールはZephyr Pro/Aerialなら設定できるようです

*9:マニュアルにはPro/Aerealのみと書かれていましたがLiteでもできました

*10:Transform - Scaleは、ライティングや物理を入れるときには1(等倍)であることが望ましいのですが、今はまだ置いてみるだけなので

*11:劇場公開時のパンフレットより「242cm(アンドレ・ザ・ジャイアントより大きい)」

Unity #Zenject完全に理解した に行ってきました

株式会社ミクシィさんで開催された『Unity Zenject完全に理解した』に行ってきたメモ。

connpass.com

配信アーカイブもあります。すばらしい。はじめ機材トラブル等ありますが解消します(ネタバレ

www.youtube.com

Zenjectとは、オープンソースのUnity向けDI(Dependency Injection)フレームワークです。 Zenject以前に「DIをよく知らない」という方は、まず、とりすーぷさんの『インタフェースの使い方』から見るのがいいでしょう。ここで、DIというものがなぜ必要か、なにを解決してくれるものか、がわかるはずです。

もし『インタフェースの使い方』が何を言っているのかわからないのであれば、今日のところはUnity仙人さんの『Zenjectはじめの一歩:ゲームデータをScriptableObjectでInject!』だけにしておくのがいいのではないでしょうか。

この手のツール・フレームワークは、手段から入ってしまうとマズロー*1の言う

ハンマーを持つ人にはすべてが釘に見える

状態に陥りがちです。

Zenjectのような強力な手段を乱用すると、結果的にそのデメリットだけがプロジェクトに残ってしまうことになりかねません。(完全に、とは言わないまでも)ある程度は理解した上で導入していくことをおすすめします。

ゲーム案件にZenject導入した経験を語る

かせ(@KaseliaePenguin)さん

実際のプロダクトにZenjectを導入した経緯(目的)、試行錯誤したこと、どの範囲に適用すべきか、適用する上での注意点など盛りだくさん。

  • SceneContextを4階層(System, Data, Env, Logic)にしてそれぞれの扱う範囲を明確化し、切り替え(本番とデバッグの置き換え等)を制御
  • Bind時のAsSingle(), AsCached(), AsTransient()の違い
  • [Inject]を書いたフィールドのバインドはnew()の後に行なわれる
  • SceneContextの理解が大事
  • InjectするものにはInterfaceを切り、InterfaceをInjectすること
  • Bindはリフレクションを使うので遅い
  • 真価は運営フェーズに入ってからのはず

speakerdeck.com

文脈を操る 美しきZenjectプロジェクトからの眺め 〜Contextの扱い方と活用方法〜

Mikito Yoshiya(@mikito0521)さん

4種類あるContextの階層構造と、またそれを入れ子にできる話、実際にリリース版とデバッグ用のContextを切り替える例など。

  • Contextを意味のある単位に分割して切り替える
  • ProjectContext, SceneContext, SceneDecoratorContext, GameObjectContext
  • それぞれ入れ子にできる
  • IDisposableを実装すると、Contextが破棄されたタイミングでDispose ()を呼んでくれる
  • 大事なのはInstallerの設計。Contextとの組み合わせ
  • 依存がわかりにくくなるので、SceneContextは二階層くらいにしておく。小さいものはGameObjectContextにまわす

www.slideshare.net

インタフェース完全に理解した

とりすーぷ(@toRisouP)さん

C#のInterfaceの話。設計の話のほか、拡張メソッド、明示的な実装を書けるといった話。

  • Interfaceには必ず利用者がいる。利用者側のPackageに置く。利用者側でコントロールできる
  • 拡張メソッドに実装を書くことができる。traitっぽく使える
  • structにInterfaceをかぶせる(実装する)ことができる
    • IEquatable<T>を実装すると、Equals()の振る舞いを自分で書ける
  • 明示的な実装。InterfaceName.MethodName()と書ける。すると、Interfaceにキャストしないと呼べない

niconare.nicovideo.jp

Zenject完全には理解できなかった〜実運用におけるアンチパターンとその回避策〜

のたぐす(@notargs)さん

実運用で問題となるアンチパターンの話。Zenject自体への依存を下げるMethod injectionや、処理負荷を考慮した適用範囲の話など。

  • ZenAutoInjecter
  • Method injection: フィールドでなく初期化メソッドに[Inject]を指定できる
  • MonoBehaviorをInjectするとき、FromComponentInNewPrefab()でなくFactory経由で行なう
  • 頻繁に使うものはプールする、そもそもDIしない
  • pure C# classにのみ適用するほうがいい
  • Zenjectはハイリスク、ハイリターン

docs.google.com

Zenjectの機能をご紹介 〜テストの巻〜

@nozomin770 さん

Zenjectを適用したプロジェクトのEdit mode testで使うZenjectUnitTestFixtureおよび、Play mode testで使うZenjectIntegrationTestFixtureの話。

※スライドupされたら貼ります

Zenjectはじめの一歩:ゲームデータをScriptableObjectでInject!

Unity仙人(@lucifuges)さん

クラス設計など行なう前提でなく、データをScriptableObjectで持ち、それをScriptableObjectInstallerで切り替える話。

docs.google.com

所感

実際のプロダクトにZenjectを導入した経験談なども語られ、とても勉強になりました。皆さん、ただ「便利だよ」でなくデメリットにも言及されており、とても地に足の着いた内容だと感じました。 また、ContextやInterface、テストなど、それぞれフォーカスされた箇所が異なるセッションで構成されていたのもよかった。

自分ではまだ、DIが生きるほどの規模のものを作っていないのですが、今回の知見を取り入れて良い設計を目指していきたい。

参考

Unityゲーム プログラミング・バイブル

Unityゲーム プログラミング・バイブル

*1:心理学者のアブラハム・ハロルド・マズロー。欲求5段階説の人

Drecom Tech Espresso #6 "おなかソフトのDontDestroyOnLoad" に行ってきました #おなかソフトのドンデス

ドリコムさんで開催された『Drecom Tech Espresso #6 "おなかソフトのDontDestroyOnLoad"』に行ってきたので雑なメモ。

drecom.connpass.com

伊藤周さん、@toru_inoueさん、女子大生のとりすーぷさん、西村拓也さんのパネルディスカッション形式で進行されました。写真撮ってなかったけどこんな感じで進行。

とりすーぷさんは若干遅延のある系?女子大生でした。すばらしい。

西村さんの新刊

ダービースタリオン マスターズで学ぶ ゲームUI/UX制作 実践ガイド Unity対応版

ダービースタリオン マスターズで学ぶ ゲームUI/UX制作 実践ガイド Unity対応版

Singletonについて

  • 捨てるコードとか、逃げ場があるところだと使うけど、テスト書きにくいのでまともなコードでは使わない(井上さん)
  • SceneManagerとか、もともとUnityでstaticなものをラップしたSingletonは使う(とりすーぷさん)
    • 急ぐときは仕方ないときもある
  • Sigletonなしで作ってみたら、めんどくさい(西村さん)
  • シーンをまたいで引き継ぐとき、サウンド、オーディオには使う
  • Zenjectの機能でSingletonなオブジェクトを持てるので、いわゆるSingletonMonoBehaviour的なものは使わない
    • [8/1 追記] 問題なのはSingletonなオブジェクトそのものではなくstatic変数による参照保持なので(テストが書けない原因)、Zenjectを使えばテストではモックに差し替えることも容易で問題ない、という話。とりすーぷさんから補足いただいて追記
  • MainThreadDispatcherみたいなものとか、よくあるパターン
  • .NET 4.6ではLazy<T>が使える。C# in Depthに書いてあるパターン
  • テストしなければよい(暴論)
  • ステートを持たせなければよい、シーンをまたいで引き継がなければよい
  • Singleton自体は悪くないが、他の人に色々追加されてしまう

Sceneを切り替えるか否か

  • オブジェクトの引き継ぎ、管理コストを減らしたいので、1シーンで実装しよう、という本になってる(西村さん)
    • DontDestroyOnLoadしたオブジェクトの管理がたいへん
    • チーム開発だが、Sceneのヒエラルキーは触らないのでコンフリクトは発生しない
    • prefabで切り替ている
    • テストプレイのための工夫をしないと常に最初から実行になる
  • MultiSceneを使っている。ViewのシーンとModelのシーンを分けて重ねる(とりすーぷさん)
  • Zenject便利

MVP, MVC

  • チームによる(井上さん)
  • MとVが密結合になると壊れやすい。今はMVPに統一している(とりすーぷさん)
    • 個人開発であってもルールがあると迷いがなくなる
  • コンシューマーから来たので馴染みがない考え方だったが、気づいたらMVPになってた(西村さん)
    • アウトゲームはPassive ViewのMVP
    • インゲームはSupervising Controller
  • uGUIはMVP、インゲームはそうでなくイベントをReactiveXで扱っている(とりすーぷさん)

画面に写ってたのたぶんこれ

qiita.com

サウンド系

  • Singletonで作って呼び出す形、もっといい方法はないか
  • CRI ADX2 LE 個人開発で使える。UnityのAudioMixerは馴染まなかった(とりすーぷさん)
  • 自作するならSingleton、どうせテストしない(井上さん)
  • ボタンを押したときに必ず通る処理があるので、そこでデフォルトの音を鳴らすようにして漏れをなくしている(西村さん)
  • 鳴らすサウンドの指定はenum。stringは事故が怖い

ネットワークライブラリ

  • UNETの話はしたくない
  • 選択肢は、Photon Cloud、モノビットエンジン
  • PhotonRx作った(とりすーぷさん)
  • もしくは自作する

niconare.nicovideo.jp

所感

かなりUnityを使い込んでいる方々による生々しい話が聞けて、とても有意義な勉強会でした。 すでに第2回開催の話も出ているようで、期待しています!

今日から始めるVTuberワークショップ#01 でTAをしてきた話 #vtuberjustdoit

7/21に開催された『アナタもなろう! 今日から始めるVTuberワークショップ #01(PANORA×デジタルハリウッド大学大学院)』にて、Unity班のTAをしてきた所感など。

vtuberjustdoit.peatix.com

VTuber(Virtual YouTuber)については、つい昨日も『Vカツ』や『バーチャルキャスト』、『カスタムキャスト』といったサービスについての発表があったりと、はじめるためのハードルが日々取り払われているような状況ですが、このイベントは

という、3つの「つくる」側にフォーカスした*1ワークショップで構成されていました。

私がお手伝いしたのは、Unity上に3Dモデルを置き、HTC VIVEで頭部と両手をトラッキング+IKでモデルの姿勢制御をする、という、『バーチャルキャスト』の原型のようなものを作れる(少なくとも仕組みがわかる)ものでした。 演者として「なる」のが目的であれば素直にバーチャルキャストを使えばよくて、「似たようなものを作りたい」「仕組みを知りたい」という人向けのもの。

数名づつのグループに別れ、講師のようてんさん作の"YVTuber"をまず体験、続いて操作する3Dモデルを差し替える演習を行いました。

github.com

※演習を終えた状態が、ブランチvrm-aliciaにあります(たぶん)

f:id:nowsprinting:20180728170950p:plain

ワークショップの課題(のレベル等)設定については下記ようてんさんのエントリにも書かれていますが、準備時間の不足、受講者ターゲット設定の曖昧さなどあり、期待していたものと違った、という方が多々いらしたのではないかと思います。

VTuberワークショップで アバターシステムUnity講座らしきものをしてきました #vtuberjustdoit - ReDo

進行も、基調講演後にPCとVIVEのセットアップとなり*2受講者の方々をお待たせしてしまった上、演習のほうも資料の不備と私の予習不足が重なってしまい初回に時間がかかって二回転しかできず、申し訳ない限りです。

ただ、初回が終わったあとは課題に限らない(雑談に近い)質疑応答を受講者の方々とする余裕がありました。3Dモデラーの方、実写系VRを制作している方など、普段自分の周りにいない職種の方々と、VTuberというものを接点にお話する機会を得られたのはよかったです。

補足

ワークショップでは無償で利用できるXR Mecanim IK Plusベースでしたが、有償のものもUnity Asset Storeにあります。またIKに限らずより便利に、よりリッチな表現をするためのアセットもあります。

気になるアセットを試してみたい(試してから購入したい)という方のために、『Unityアセットお試し会@Future Tech Hub with Unity』が度々開催されています。次回開催は未定ですが、下記ページに案内が出るはずです。

peatix.com

また、7月中に$30以上のアセットを購入すると、Bio IKがもらえるキャンペーンが開催されています。

https://assetstore.unity.com/g/july-promo-activation-jp

*1:これを書いていて気づいたのですが、『なろう』というタイトルから来る演者向けな印象と、ワークショップの内容がアンマッチなのが色々な迷いや不幸を生んでしまった元凶のような…

*2:贅沢を言えばPC+VIVEのセットがたくさんあればとかキリがないのですが

Unityアプリを受託開発するときのライセンスとディレクトリ構成について

Unite Tokyo 2018のユニティ・テクノロジーズ・ジャパンさんブースで聞いたことのメモ。勘違いしていたので聞いてよかった。

受託開発の場合、受託開発する側は当然Unityライセンス必要として、顧客が納品されたアプリをApp Store等でリリースするケースで、顧客に何を買ってもらえばいいかの話。

Unityライセンス

原則は

「Unityライセンス(サブスクリプション)は、エディタを開いたりビルドしたりするのに必要」

とのことなので、

  • 受託側がビルドしたアプリを受け取って公開するだけなら、顧客(パブリッシャー)はUnityライセンス購入は不要
  • 受託側からソース(Unityプロジェクト一式)を受け取るとしても、Unityエディタで開いて検収・ビルドしないのであれば、Unityライセンス購入は不要
  • ソースをUnityエディタで開いて検収・ビルドする場合でも、エディタを使う期間だけサブスクリプションしていればよく*1サブスクリプションが切れてからもApp Storeに公開し続けて構わない

Asset Storeで購入したアセット

  • 納品物にソースとして購入したアセットを含めるのは再配布として扱う。再配布の扱いは各アセットのライセンスによる
  • 購入したアセットは除外して納品したとして、納品後、顧客側で個々のアセットを購入するタイミングでアセットがバージョンアップされている場合がある。Asset Storeから過去のバージョンのものはダウンロードできない点には注意

ディレクトリ構成の例

Asset Storeで購入したアセットを隔離する必要は感じていたので、以下のようにしています、という設定例です。以降はUnityさん推奨というわけではないのでご注意ください。また、後述しますが完全なものではないので、いいアイデアがあればぜひ教えてください!

Unityプロジェクトのディレクトリ構成

まず、プロジェクトのAssetsディレクトリ下に自社開発分を隔離するディレクトリを切ります(以下MY_PROJECT)。この下に、Editor, Prefabs, Scenes, Scripts, Tests*2など必要に応じて配置していきます。

Asset Storeや.unitypackageファイルをインポートしたものは、Assets/直下に配置ます。ディレクトリ名で別れてくれるものが大半ですが、EditorやPluginsの下に置かれるものもあるのでまとめて除外するためです。

.gitignore

.gitignoreファイルのベースを取得します。

$ curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/master/Unity.gitignore

これに以下を追加します。

# PlayMode testing cache(たぶん)を除外
Assets/InitTestScene*.unity*

# 公開 or 納品するものであれば、自身のプロジェクト以外のAssetsを除外
/Assets/*
!/Assets/MY_PROJECT*

MY_PROJECTの後ろに/をつけてしまうと.metaファイルが漏れるので注意。

またもし、Assets/Editor/下やAssets/Plugins/下に置いているファイルがあれば、個別に除外指定(!ではじまる行)を追加してください。

課題

この方式では、以下の課題が未解決です。

  • リモートリポジトリをcloneしてそのままビルドできない。これはCI(continuous integration)を使用するときに致命的です。
  • Asset Storeからインポートしたアセットに独自の修正を加える場合。MY_PROJECT下に複製して修正するなどできますが、ライセンスを考えると問題ですし、差分に気づかない恐れもあります。
  • Assetの設定を自身のフォルダ下に格納するタイプの場合。EasySave2とか、Cross-platform Native Pluginsとか。これも差分に気づきにくいのがつらい。

このうちCIについては、開発機にあるフルセットのプロジェクトをUnity Collaborateに上げて、Unity Cloud Buildでビルドする方式を取っています。一人でやっているので大丈夫なのですが、チーム開発だと厳しい運用だと思います。

*1:とは言え最短1年ですが

*2:EditMode Testsだとprivateメソッドを直接呼べなくてストレスなのでPlayMode Testsを使っています

SRE-SET Automation Nightに行ってきました #automation_night

メルカリさんで開催された『SRE-SET Automation Night』に行ってきました。

この勉強会は、SRE(Site Reliability Engineer)およびSET/SWET(Software Engineer in Test)な人を対象をした、"自動化"にフォーカスしたもの。

connpass.com

以下、雑なメモ。

Data processing, workflow and us ~How to manage automated jobs~

speakerdeck.com

  • @syu_creamさん。メルカリのSREチーム
  • ログをBigQueryに送る部分を改善
    • fluentd
    • 当初、シェルスクリプトとcronで実現。途中経過が見えない、エラー時の再実行が困難などの課題
    • 会社の成長にともなってログも大きくなってきたので改善したかった
    • 改善
      • Digdagを利用。ジョブの進行をビジュアライズ、再実行が容易に
      • ログサイズを事前にsplitするようにした(upload前でなく)
  • 統計
    • オンメモリ処理だとメモリがつらくなってきた
    • シーケンシャルに実行していたが時間がかかるので並列化したい
    • 改善
      • Full managed ETL(extract, transform, and load) serviceを使う
      • Apache Airflowでジョブ管理

レビューのコストを削減するための施策

www.slideshare.net

  • @tarappoさん。DeNAでSWET、iOS/Android Test Night主催
  • レビューのコストが高いので、できるだけ機械に任せたい
  • レビュー対象は色々あるが、今回はテスト観点のドキュメントの話
    • ここで言う「テスト観点」は、対象プロジェクトにおいてテストで確認すべきポイントを機能単位にまとめたもの
    • QAが書いている
    • GitHubを使い、Pull Request(以下PR)でレビューを行っている
  • 運用の問題。コメント数が最大174のものもできた
    • 指摘を修正されてもチェックしきれない
    • レビュアーとして途中参戦したくない
    • どのPRをレビューすべきか判断できない
  • PRの内容が記載されていない、タイトルにWIPがついたままでレビュー依頼されるのが一因
    • Dangerで事前チェックすることで回避
  • 文書の問題はtextlintでチェック
    • 対象プロダクトの固有名詞辞書で表記ゆれのチェック
    • ですます調、である調、弱い日本語の禁止(〜かもしれない、〜と思う)
  • PRの前に各自textlintを流す(必須ではないけど、ほぼやってくれる)
  • PRのコメントに"review"と書く → CIでtextlintとDangerが走る → okならレビュアーにmentionが飛ぶ
    • JenkinsのGitHub Pull Request Pluginで、特定フレーズでキック
  • Danger
    • 内容のチェック
    • タスクが全て完了しているか、textlintが通っているか
    • 最終コミットがgreenになっているか
    • 通ると、ラベル"In Review"がつく
  • 導入後、表記ゆれ、typoが減った。PRが見やすくなった
  • 今後の課題
    • 辞書の登録が面倒
    • 定量的評価をしたい
    • レビュアーの選定を自動化したい(集中しないようにしたい)
    • API Docに適用できないか
    • Jenkinsからの脱却

Reliable Mobile Test Automation

www.slideshare.net

  • @vbanthiaさん。DeNAでSWET→メルカリでSET
  • Appium Docker DemoとかSTF Appium Exampleとか公開
  • Test Automation Lift Cycle
    • モバイルにおいて、自動テストだけを信じてリリースできるか?(会場では自動テストをやっている人は多かったが、信じられるか?の問に挙手した人は1人だけ)
    • 機能が増えてくるとQAチームがパンクする。振り返りで"We need automation!"となる
    • Development Teamから分割してSET/SWETなどに分けるケースが多い?
  • ツール選定・導入は比較的簡単にできる
  • たくさんテストを書く
  • そのテストをリリースまで使うのが難しい。問題になるのは、
    • Flaky tests(不安定なテスト。様々な要因で成功したり失敗したりするもの)
    • Test execution environment(実機を含めたテスト実行環境)
  • 結果、テストが信じられない。使われなくなり、メンテされず、捨てられてしまう
  • Flaky Tests
    • 原因として
      • User interface issue
      • Backend issue
      • 3rd party service issue
      • Hardware issue
    • problem is not flaky test. 問題は、テストがflakyなことではなく、テスト実行中に何が起きたか我々が知らないこと
    • 対策は"Record everything!"
      • Screenshots, Video
      • ADB logs
      • Timestamp of each UI action and test assertion
      • Test script logs
      • Appium logs
    • レポートの改善
  • Test Execution Environment
    • Cloud Serviceが使えればベスト、誰でも使える環境
    • 以前の発表、"Android e2e testing at mercari"を参照
    • Google Cloud Storageにapkをuploadして、DockerでOpen STF、Circle CIでDocker imageビルド、テスト実行
  • デモ
    • Slack上の対話Bot(名前は"BB-8")で実行できるようにしてある
    • UIで、ビルド番号、複数のデバイス、複数のテストケースを選んで実行できる
  • Mobile test automationはチャレンジングだが不可能ではない

Magic Podの活用を具体的に考えてみた

www.slideshare.net

  • 戸田さん
  • Magic Podについて、Selenium IDEを使っていた層に向けたもの、という印象を持った
    • コード書ける人、Excel+手動テストの人、という人たちがいて、その中間の層
  • アプリが完成してから自動テストを作るのでなく、ワイヤーフレームから仮のテストケースを作っていけばQAも並列作業できるのでは?
  • CLIもある。Travis CIでは検証した(TRIDENTさんのブログで公開)。Circle CIは検証中

Prometheusを導入した話

セキュリティ強化のための自動化

speakerdeck.com

  • @manabusakaiさん
  • freeeでは人やお金に関する情報を扱っている。情報漏えいは厳禁だし、よく攻撃もされる。
  • 1,000台のサーバをSRE 3人で見てるので、自動化で対応
    • セキュリティパッチ、すぐ適用したいけど難しい
    • 外部からの怪しい攻撃は自動的に遮断したい。攻撃されてから気づくことが多い?
  • CodeBuildを使いAMI作成
    • Golden AMI方式
    • 以前は、脆弱性が発見されると手分けしてやっていた → CodeBuildでPackerを流す方式に
    • 1コマンドだけ投入、並列実行できるので1hくらいで全インスタンス入れ替えを完了
  • AWS WAFを使った攻撃の自動遮断
    • 攻撃側のIPアドレスは頻繁に変わるので、security groupなどでは対処しきれない
    • ロードバランサにAWS WAFを導入、DoSっぽいアクセスがきたら、403を返してくれる
    • LBで遮断できるのでWebサーバの負荷は上がらない
    • 一次対応がこれでできるので、他の対処が必要な攻撃であっても人間は余裕をもって対処できる

1人インフラ運用チームで、自動化の作業時間を確保するためにやっている(た)こと

speakerdeck.com

Automation基盤提供のしかた

  • @tnirさん
  • 実行履歴が取れることが大事
  • 実行タイミングを制御できること
    • ナイトリービルド
    • マニュアル実行
    • イベントドリブン
    • 自動再実行、マニュアル再実行
  • 実行命令系との連携
    • dev: SCMとの連携
    • ops: Infrastructure as Code
    • ジョブと変数の分離
  • GitLab CI/CDを使っている
  • 社内への普及活動
  • 業務上は困ってないが、デザイン/パフォーマンスには課題。ほかも検証してみたい

所感

会場にSREな人は少なかったようですが(私も門外漢ですが)、"自動化"というキーワードでくくって広範囲な話が聞ける機会となり、とても面白かったです。

いずれも、導入から運用、改善のスパンが長くなる話なので事例そのものが貴重ですし、かつ今回は単に「試してみた」「導入してみた」を超えた話が聞けて大変ありがたいイベントでした。

第2回以降も(自動的に!)開催されそうな方向なので、期待して待ちます。

システムテスト自動化カンファレンス2017-2を開催しました #stac2017

ヤフー株式会社さんで開催された、テスト自動化研究会の旗艦イベント「システムテスト自動化カンファレンス2017-2」にスタッフとして参加してきました。

testautomationresearch.connpass.com

通算5回目、年1回の開催ですが、昨年分が15月にずれ込んでしまったため「2017」と銘され、今回が「シン・2017」ということになります。まぎらわしくてすいません。

今回はチュートリアルのTAとしてお手伝いしたため余り講演は聞けなかったのですが、今回からはじめた公募セッションやLTが入ったことで、扱う幅が広がったように思え、有意義なカンファレンスであったように思います。

Magic Pod チュートリアル

チュートリアルはキャンセルも出て想定より少ない人数での開催でしたが、その分TAの目が届きやすくなり*1、ほとんどの方がInstagramアプリを題材にした実践課題*2まで完遂できたようで、正直ほっとしました。

内容は、モバイル向けテスト自動化ツールであるMagic Podの使いかたを紹介するもので、これはappium導入のハードルとなっている「操作対象のUI要素を指定するためのロケータの検出」を自動化し、また、テストケースを(テストコードを書くのでなく)ブラウザ上のマウス操作で作成・実行できるというツールです。

Magic Podは無料で使い始めることができますので、興味を持たれた方はぜひお試しください。

www.slideshare.net

講演資料

以下、拾えた範囲でスライドを。追って、テスト自動化研究会の"イベント&アーカイブ"のページにレポートが出るはずです。

テスト自動化と機械学習(STAR機械学習分科会紹介)

TODO: 公開されたら貼ります

翻訳者の同僚が語る「初めての自動テスト」

www.slideshare.net

9月に発売された書籍『初めての自動テスト』について、翻訳者の玉川さんが本日来られないとのことで、同僚である太田さんによる講演。

書籍はこちら。

初めての自動テスト ―Webシステムのための自動テスト基礎

初めての自動テスト ―Webシステムのための自動テスト基礎

GebとSpockではじめるシステムテスト自動化

www.slideshare.net

楽天のレジャー・サービスにおける自動化の取り組みとその効果

www.slideshare.net

How we automate E2E tests at Mercari

TODO: 公開されたら貼ります

TypeScript + PhantomJSを利用した効率的なテスト実施

speakerdeck.com

SI-Toolkitでテスト自動化を実現する現場で遭遇した出来事

www.slideshare.net

自動化困難な状況での活動方法

www.slideshare.net

LT

テスト自動化の前の1.5年にやったこと

楽天の荻野さんのLT。タイトルはうろ覚えですすいません。

レガシーなシステムにテスト自動化を導入したときの、スクリプトを書く前に実施した、開発基盤の整備やQAマネージャのレベルアップといった施策の紹介。それらを整える期間は目に見えた進捗は少ないが、「あとはスクリプトを書くだけ」になってから一気に自動化が進んだ、というお話。

IoT基盤を活用したテスト時間の短縮

折田さんのLT。自動テストを実行するためのPCをたくさん積むという話をよく聞くが、PCはテスト対象の動作待ちがメインなのでスペックは低めでよく、むしろ夜間に通電したまま放置できるものが望ましい、そこでRaspberry Piを使う、というお話。

スタッフ反省会で実機(名前がR2-D2とK-2SO!)を見せていただきました。次は動いてるところが見たい!

テストも開発もするモバイルエンジニアのためのXCUITest/Espressoのすすめ

speakerdeck.com

appiumのメリットは語られるけど、実際にはそれほど楽に享受できるわけではなく、それならばiOSはXCUITest、AndroidはEspressoを使うほうが便利、というお話。

ちなみに私は、開発者テストとしてのIntegration Testingであれば完全に同意。システムテストとして、End to Endとして、という話になると、やはりappiumなどでリリース向けのパッケージ(ipa/apk)をテストすべきかな、とは思います。割り切りですが。

フォローアップのエントリはこちら。

woshidan.hatenablog.com

gaugeによるe2eテスト

テスト自動化ツールGaugeの紹介

テストケース構造をモデル化しよう!:テストカタマリー紹介

www.slideshare.net

*1:逆に介入が多すぎたと感じた方がいたら申し訳ない

*2:ログイン・ログアウトだけでも色々な振る舞いがあって複雑なのです