Mikimemo

個人的な技術・開発メモやポエム

ZenjectDefaultSceneContractConfigで依存するSceneContextを確認用に自動ロード

UnityのZenjectの他の機能の紹介をしようかと思ったところ、 ZenjectDefaultSceneContractConfigという機能を発見。

おそらくv6.1.0くらいから追加されたっぽいんですが、 個人的には全俺が湧く感じの機能、圧倒的僥倖だったのでこちらを紹介します。

Project Contextの使いにくさ

まず、Zenjectを使う上で、ProjectContextというものがあります。 これは、何かしらのScene Contextが読み込まれる前に、 必ず自動的にロードされるContextで、 アプリケーション起動中に常に必要なものをBindしておくには非常に便利なものです。

ただし、このProjectContextには「どんなシチュエーションでも有無を言わずロードされるため、コンテキストの差し替えが効かない」 という積極的に使用できない欠点がありました。 例えば、タイトル画面がら起動する通常フローはサーバーへ通信を行うコンポーネント群を利用するが、 Editor上での特定テストフローの場合は、 ローカルのフィクスチャファイルからデータをロードするモックコンポーネント を利用する場合等が挙げられます。 これらのような、場合によってはInstallerを差し替えたいというケースの場合は ProjectContextではやりにくかったのです。(内部で処理を分岐させれば可能)

ということで、せっかく自動で前提条件をロードしてくれるContextがあるんですが、 切り替えが生じるContextはSceneContextで実装し、 Scene ContextのAuto Runを切った上で、 自前で依存するSceneContextをロードするフローなどを作ったりしてました。

ZenjectDefaultSceneContractConfigによる自動Contextロード

たとえば、以下のようなSampleシーンのContextが DefaultシーンのDefaultというContract NameのContextに依存しているとします。 こういったシチュエーションの場合、 このシーンの起動にはDefaultシーンを予めロードしておく必要があります。

f:id:miki05:20180731021245p:plain

ゲーム起動の通常フローならば、 おそらくDefaultシーンを誰かがロードするようになっていると思いますが(Build Settings / LoadLevel 0でも)、 EditorでSampleシーンを編集後、動作を確認したい場合、Playボタンを押して、このシーンから直接始めたくなります。 つまり、依存するContextは自動でロードしてほしい。

これが、 ZenjectDefaultSceneContractConfigという機能を使うとできます。

使い方はシンプルで、 まずは、Resources以下にZenjectメニューからZenjectDefaultSceneContractConfigアセット作ります。

f:id:miki05:20180731005932p:plain

そして、デフォルトロード対象のContractNameとシーンファイルを設定します。

これで完了です。 Unity上でPlayボタンを押すと、自動的にDefaultシーンがロードされ再生が始まります。 (停止時に自動ロードされたシーンはアンロードされません)

f:id:miki05:20180731013249p:plain

また、このZenjectDefaultSceneContractConfigには、複数のDeafult Contextが登録でき、 依存関係の解決を再帰的にできるようです。 例えば、あるScene ContextにはAというContextを持つシーンが必要で、 A ContextはBというContextを持つシーンが必要な場合 A, B両方ともZenjectDefaultSceneContractConfigに設定しておけば、 双方自動でロードをしてくれます。

テスト用のContextとのスイッチ?

さらに、ZenjectDefaultSceneContractConfigで設定したContextは、 Scene ContextにおいてParent Contract Nameが設定されている状態かつ、 まだシーンにロードされていないときのみ、ロードの処理が走ります。

つまり、予めDefaultシーンのContextと同じContract Nameを設定した別のContext、 例えばテスト用のDefaultシーンを用意しPlay前にロードしておけば、 コードを一切変える必要なく、動作の切り替えができそうです。

f:id:miki05:20180731013817p:plain

ちなみにこのZenjectDefaultSceneContractConfigはEditorのみの機能のようで、 通常のビルドでは明示的に依存シーンをロードするフローが必要です。 そのため、今回のように、あるシーンが他のシーンに依存するが、 確認フローやテスト等で直接起動したい場合のワークフローに有効そうです。

むしろEditorのみの機能だとしたら、 DefaultSceneContractConfigの方をモックやスタブしたContextにしておいたほうが良いのかもしれませんが。

ZenjectのScene Decorator Contextの使い方

最近、UnityのプロジェクトではZenjectを使っており、 1年くらい実プロジェクトで運用してようやくコツがわかってきた気がする。

しかしながら、 Scene Decorator Contextがどんなものかをあまり理解しておらず調査したのでメモ。

そもそもZenejectのContextと親子関係

ZenjectのContextには以下の4つのタイプがある

  • Project Context
  • Scene Context
  • Scene Decorator Context
  • GameObject Context

この中でProjectContextはゲーム起動時に必ず生成される。 そして全てのContextの親である。 そのためどんな環境でも利用すべき神的な何をBindするには良い。 ただし、テストのことも考慮するとテスト環境でも利用するマジでゴッドなものに限る。

そしてScene Contextはシーンをロードすることで、子となる新しいContextを生み出すことができる。 GameObject ContextもScene Contextの子になることができるし、Factoryを使うことで動的に子となるContextを生み出すことができる。

f:id:miki05:20180724005934j:plain

こんなカンジでContextの親と子を設定したり、 ある意味のある塊や粒度ごとにContextを切り分けることで、 カプセル化やContextの差し替え、動的な生成・破棄などが可能になってくる。

ただし、親子関係が存在すると言うことは、 Context間に依存関係が生じるということで慎重に用いる必要がある。

Scene Decorator Context

Scene Decorator Contextは親子関係を作らずにContextの分離と差し替えを可能にする仕組みだ。 もしくは、Decoratorパターンのように、対象Contextに何の変更もなく機能を付与する仕組みと言える。

たとえばある1つのゲームが起動している状態を3つのScene Contextに分ける場合を考える。

  • Stage Scene Context
  • UI Scene Context
  • Main Scene Context

ちなみに、Contextを分割するメリットは、 StageやUIをデバッグ用や別のセットに差し替えたり、個別にテスト等を行えるようにすることが主だと思う。

で、この場合、Main Scene ContextがEntryとなってゲームが駆動する場合、 Scene Contextの親子関係を作るとしたら、いくつかパターンがあるが、例えば以下のようなものが考えられる。

f:id:miki05:20180726221652j:plain

Zenejectは途中のバージョンからParentを2つ以上もつことができるようになったので もしくはこう f:id:miki05:20180726221704j:plain

反面、Scene Decorator Contextのイメージは以下のようなカンジだ。

f:id:miki05:20180726222015j:plain

つまり、それぞれのScene Contextが親子というより、なんとなく同列なカンジになる。

ここで、親子関係を作る方法と比較して、 Decorateする方法の違いを挙げると、 Decorateする方法は相互にContext内のContainerに参照ができる点である。 親子関係を作る方法に置いて、上記の例のパターンではStage SceneやUI SceneからはMain Sceneを参照できないが、 Decorateする方法はStage SceneやUI Scene、Main Scene内のContextをあたかも同一かのように扱うことができる。

なお、実際Editor上の設定方法は以下みたいなInspectorとシーンの状態になる。 注意点としてはシーンをロードする順番(Hierarchyの順番)はDecorator Scene => Decorated Sceneにする必要はある。

f:id:miki05:20180726212835p:plain

Scene Decorator Contextのメリットは?

Scene Decorator Contextのメリットは 対象のContextや親子関係を変更なく、機能の一部の差し替え、もしくは機能の追加ができる点だ。 たとえば、 特定のケースのときだけDecoreted Sceneを読み込んで機能を付与(対象コンテキストを装飾)することができる。

これは、複雑な親子関係の設定を、ある程度シンプルなものにしてくれる。 Scene Parentingな方法だと、親子の関係を慎重に設計し、 階層構造を意識しながらParent Context Contract Nameとシーンのロードをしなければならない。

Scene Decorator Contextを導入することで、 アプリケーション本筋である大枠の文脈(Context)の依存関係をざっくりと意識するだけでよくなる。

どんなときにDecorator Contextが使える?

未検証だが多分以下のようなUseCaseが考えられるおもう

  • デバック用のコマンドやUIの機能を特定のScene Contextに付与する
  • Parentingとして意識したくないScene Context(大筋外の文脈)の分割
  • チュートリアルフローなど?

そのScene Contextは親子?

正直いうと、Scene Decorator Contextの機能は、 親子関係を工夫することである程度まかなえる気がする。

しかしながら、かねがねZenjectをしばらく利用してきたわけだが、 本当に概念上の親子関係なのか疑問に思うパターンもいくつかあった。 例えば、上記の例だとStage ContextとMain Contextってどっちが親なん?というか親子関係なん?といった具合である。

さらに、Scene Contextの親子関係の依存周りがネックになりやすいという印象を持った。 なにせZenjectはContext同士の依存関係を解決してくれるが、 Sceneの依存関係は自動で解決してくれない。 Zenjectのためにシーンのロードのお膳立てをする必要あり、 そのあたりが複雑になると(何重にもScene Parentingを行うと)わけわからんくなる。 さらに言うとHierarchyビューで親子関係の視覚化が行われないので、とっつきにくいのもある。

そもそも、親を複数持てるということも混乱を招きやすいように思う。 親ではなくDependancyみたいな命名だったらもうちょいわかりやすいが。 で、クラス間の依存解決をサポートするためにDI Containerがあるはずなのに、 Context間の依存に苦しむのは本末転倒感がある。

そのため、親子関係の設定は極力シンプルにしておきたい気がする

まとめ

以上、Decorator Scene Contextについての機能と自分の見解でした。 最後ほうDecorator Scene Context推しみたいな主張になってしまいましたが、 時と場合によって使い分けるべきなんでしょうね。

自分の中では、 以外と使いどころはあるのかなと思っているので、導入を検討してみます。

複数Python環境を切り替える

ローカルの開発マシンの場合、複数のPythonのバージョンを使い分けたいことがある。

というより、 Rubyにおけるrbenvとかrvmやらを使っていた身からすると、 こういう環境は普通に導入しておきたい。

これにはpyenvを使うといいみたい。

導入

$ brew install pyenv

bash_profileに以下を追加

export PATH="$HOME/.pyenv/shims:$PATH"

使いかた

Pythonのバーションインストール

以下で利用可能なバージョンの一覧を表示

$ pyenv install -l

バージョン指定でインストール

$ pyenv install 3.7.0

バージョンの切り替え

versionsでインストールされているバージョンを確認

$ pyenv versions

globalコマンドで切り替え

$ pyenv global 3.7.0

参考

Unityゲーム プログラミング・バイブルの出版&重版、そしていろいろ

発売からだいぶ時間が立ってしまいましたが、Unityの中級者向けの書籍に寄稿させていただきました。

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

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

総勢16人の著者さんにより、ゲーム制作に必要な様々な技術分野で今までにない深さの解説がなされているのが特徴です。そしてめちゃくちゃ分厚い。

そして、先日重版の連絡もいただきました。本当にありがとうございます。いまさらブログを書いて、ほとんど宣伝に貢献できずすいません。

ことの発端

こちらの書籍は企画の段階から参加させていただいており、どんなトピックを掲載するかということも編集の方と議論しました。

Unityの中級者向けの書籍というものは、以前Unity入門書を執筆したときから需要があるということは感じていましたが、その解説の難しさも感じていました。

それは、Unityというゲームエンジンやゲーム制作という分野の巨大さから、どうしても特定分野を深掘りするとボリュームが増え、ボリュームを抑えると特定のゲームジャンルにしか適用できない解説になってしまうというトレードオフを感じていたからです。

また、専門性の問題もあり、一人ですべての分野(アニメーション、グラフィック、ネットワーク、AI、etc..)を深く調査し解説を行う工数が現実的にあるのかという問題でした。

というモヤモヤあるなか、上記問題を解決する今回のような複数人の著者参加型のお話を頂いたのでした。

マスターデータとアーキテクチャ、ワークフロー

自分が担当したのは、マスターデータをゲーム内で扱う実践的な方法です。 マスターデータとはゲーム内のキャラの強さやアイテム名、敵キャラの出現データなど、パラメータやゲームバランスなどを設定してあるデータファイルです。

超シンプルなゲームやサンプルを作るときは例外かもしれませんが、一般的なプロダクトレベルのゲームを作る際はこのマスターデータを明示的に用意することが一般的かつ常識です。

が、しかし、ゲームを独学で作っていたりすると、このあたりの存在をあまり意識しないのではないでしょうか?(少なくとも自分が学生の頃はそんなこと意識してませんでした)ところが、複数でゲームを作っていたり、効率よく作業を進めようと思うと、このようなデータをどう扱うか、しいてはゲーム基盤全体の仕組みをどうするかということに思いを馳せることになります。

このようなゲームのアーキテクチャというトピックを解説しているものってあまりないし、初学者の人になにか参考になるものを示したいなということで、そういう内容を盛り込みました。(題目はエクセルファイルからのデータ自動インポートですが)

そしていろいろ

ひさしぶりにブログを書きました。そもそもほとんど書いてなかったのに、最後に書いてから2,3年...?

ちょっと仕事にプライベートにいろいろ打ち込んでいたのと(結婚もしました)、自分の情報なんて価値あるかなーと思うところもあり、SNSとか情報発信とかちょっと敬遠気味だったんですね。あとQiitaとか社内ナレッジに書くことが多かった。完全に言い訳ですが。

最近このままだと技術者としてヤバイという気がしてきたので、ほんとに頑張ろうかと。

あんまりまとまった記事というよりは、自分の備忘録とか多くなりそうですが。 とりあえずはてなダイアリーからはてなブログに移行した。マークダウンで書きやすい。

Twitterも再開しよう。

Unity5入門書の電子書籍版が発売されました!

先日報告しました、Unity5の入門書
「Unity5 3D/2Dゲーム開発実践入門 作りながら覚えるスマートフォンゲーム開発」
電子書籍版が達人出版会さんから発売されました。

http://tatsu-zine.com/books/socym-unity5

ご要望を頂いておりました皆様、大変お待たせいたしました。

すでに世間ではUnity5.2が出ていますが、
基本部分はほぼ変わらないので問題なく読み進められるはずです。


また、紙媒体のその後ですが、大変反響が良いようです。
発売されるまでビクビクしてましたが、本当にうれしいです。
がんばったかいがあったなぁ...

購入頂いた方や記事を書いてくださった方に感謝!



今後は、もっとブログとかでアウトプットしていこう。
が、ドキュメントを書くより何か動くものを作ってたほうが楽しいんですよね。
いつものやるやるサギ。いやがんばります。

Unity5の入門書を書きました。アセット付き!

この度「Unity5 3D/2Dゲーム開発実践入門 作りながら覚えるスマートフォンゲーム開発」
というUnityの入門書を執筆させていただきました。

アマゾンで購入できます。明日7/24発売です。

特徴1. ゲームを完成させるためのUnityの要素にフォーカス!

僕は普段から業務でUnityを使っていますが、一個人ゲームクリエーターとして、
どういったことが知りたいか、必要かということを盛り込みました。

そのため、
カジュアルなゲームではあまり使わないものや、普段の操作ではあまり触れないものよりも、
ゲームを完成させる上でなくてはならない機能を、それなりの「広さ」と「深さ」で説明するようにしました。
(イベントやオブジェクトの制御方法、サウンドやエフェクトの出し方、UIの表示やボタンの処理などなど)

また、ゲームを「作る」だけでなく、
リリース用の設定方法や広告表示に関しても掲載しました。
「Unityをつかってみたいという人」というよりは、
「Unityをつかって何かしたいという人」に向けているといってもよいかもしれません。

特徴2. ゆるロボ製作所の可愛いモデルを利用できる!

この本の一番の特徴として「ゆるロボ製作所」のキャラクターアセットをサンプルで利用することです。
このゆるロボ製作所といういうのは、自分が数年前に業務で作ったUnity製のアプリです。
http://yururobo.jp/

全部のサンプルではないですが、
5章でアシスタントキャラの「ねじ子」をベースにアニメーションやキャラクター操作について解説しています。

ねじ子が走る姿がなかなか可愛いです。
多分つくってて楽しいはず。 
モデルもシンプルなので最初のとっかかりとしては良いかなとおもいます。

ちなみに、本の表紙はゆるロボのキャラクターデザインを担当していただいた牙竜さん書き下ろしです!
もうめちゃめちゃうれしい。家宝にします!

特徴3. それなりに遊べるゲームを1から作りあげるx4!

この本のコアとなる3,4,5,6章は、
実際にサンプルを作成しながらUnityの機能や使い方を学ぶという構成になっています。
解説どおりにサンプルの製作を進めると、
ゲームとしてそれなりに遊べるものが出来上がります。

せっかく作るならゲームとして面白いものを、
さらにモバイルゲームなら友達に見せびらかして自慢できるものを!
というコンセプトです。

さらに、
サンプルは基本的にスマートフォンゲームを最初から意識しているため、
入力方法や画面サイズ、ゲームデザインなどに関して、
より実践的な方法を体験することができます。

特徴4. ゲーム開発の基本知識からUnity5の内容も知れる!

ゲーム開発が初めてという方も想定して、フレームの概念などの基礎的な知識もなるべく説明しています。
また3Dが初めてという方のために、シェーダーやライティングなどの概念を解説しています。
(自分がUnityで初3Dだったので、つまづいたところなども踏まえてます)

さらに、
Unity5でどんなことが可能になったかや、新規機能の簡単な利用方法についても説明しています。
Unity4を触っているけど、
物理ベースシェーダーやオーディオミキサーの機能も知りたいという方の参考になるかもしれません。


実物はこんなかんじです。

この本を書くにあたって

いやー大変でした。もう、Unity5巨大すぎ。

なんとか書き上げましたが、内容に関して今も悶々としてます。
構成が適切か、サンプルが適切か、
機能の使い方や説明を間違えていないか、
文章がわかりやすいか、足りていないことはないかなどなど。。。

ただ、自分なりに精一杯頑張ったので、少しでも皆様の役にたてたらうれしいです。

そして、
本当にいろいろな人にお世話になりました。
カバーデザインを担当していただいた牙竜さん、
サンプル内のBGMと効果音を担当していただいた柴田さん、
サンプル素材の作成と調整を担当していただいたランディさん、
アザラシの挿絵を担当していただいた小菅さん。

また、ゆるロボモデルの使用に関してや、
仕事面でのサポートをしていただいた上司の開さん、
ライティング周りの原稿の添削にご協力いただいた湊さん、
クソ忙しいときに本の作業で休んで迷惑をかけたつぐmeチームの皆様。

さらには、
執筆についてお声をかけていただき、
このようなきっかけをくださったサービス開発部元上司の蒲地さん、
本書の編集をご担当いただき長期間執筆をサポートしてくださったソシム株式会社 佐藤様。

この場を借りて深くお礼申し上げます。
ありがとうございました。


個人的に作業面ではいろいろ反省点もあるので、
余裕があったら次回以降にも書こうかとおもいます。

YosemiteにbrewでPandocいれた

仕事でつかってたiMacちゃんが激おもになったので、
新規にMac Book Proを使うことにしました。

Pandocをいれたのでメモ

$ brew install ghc cabal-install
$ cabal update
$ cabal install pandoc

pandocのインストールでものすごいcpu使用率になったけど...

bash_profileとかにPATH設定

export PATH=$PATH:$HOME/.cabal/bin


こんな感じにつかう

$ pandoc text.md -s -o text.html