かせノート。 2019-07-16T15:15:48+09:00 yutakaseda3216 Hatena::Blog hatenablog://blog/6653458415127723183 【備忘録】最近のこと hatenablog://entry/17680117127219020467 2019-07-16T15:15:48+09:00 2019-07-16T15:15:48+09:00 5月ごろから仕事が忙しく、ゲーム開発がほとんどできない状態に。 6月に入り、仕事は落ち着いたものの精神的に参ってしまい、東京電脳特区のお手伝い以外は、ゲームを遊んだり、小説を読んだり、アニメを見たり。 7月、PCを立ち上げて開発環境を起動する気力がなく、ズルズルとほぼ何もしない日々。 気力がある日はムービーシーン用のアニメーションを作り続ける。 サークルで開発をしていると、自分以外の進捗があることでモチベーションをあげたりすることができるが、メンバーのほぼ全員が仕事に忙殺されており、進捗がない状態が続く。 常駐案件の仕事をギリギリでこなすうちに、仕事だけで体力と気力が限界を迎えてしまう状態にな… <p> </p> <p>5月ごろから仕事が忙しく、ゲーム開発がほとんどできない状態に。</p> <p>6月に入り、仕事は落ち着いたものの精神的に参ってしまい、東京電脳特区のお手伝い以外は、ゲームを遊んだり、小説を読んだり、アニメを見たり。</p> <p>7月、PCを立ち上げて開発環境を起動する気力がなく、ズルズルとほぼ何もしない日々。</p> <p>気力がある日はムービーシーン用のアニメーションを作り続ける。</p> <p> </p> <p>サークルで開発をしていると、自分以外の進捗があることでモチベーションをあげたりすることができるが、メンバーのほぼ全員が仕事に忙殺されており、進捗がない状態が続く。</p> <p>常駐案件の仕事をギリギリでこなすうちに、仕事だけで体力と気力が限界を迎えてしまう状態になり、休みの日は熱を出して寝込んだり、何もせず無気力に天井を見つめていたりする。</p> <p> </p> <p>そんな状況を打開するために無理やり作業を開始すると、頭痛と吐き気が止まらなくなるので、対外的に責任の発生する作業も、最近は放り出してしまっている。</p> <p> </p> <p>このままほぼ何もしない日々を続けるのは、過去の自分とサークルメンバー、ゲームの完成を待ってくれている人に対して不誠実であり続けることと同義なので、それにまた苛まれる。</p> <p> </p> <p> </p> <p>折り合いがつくまで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SNS">SNS</a>や何かの集まりからは消えると思うので、よろしくお願いします。</p> yutakaseda3216 【Unity】Prefabを生成する際に、クラスに生成方法を紐付ける hatenablog://entry/17680117127008034247 2019-04-04T14:19:21+09:00 2019-04-04T14:19:21+09:00 少し走り書きになってしまっています、ご容赦ください。 内容 Unityを使用していると、必ずPrefabをInstantiateする行為を行うと思います。 その際、以下のようなコードになるのではないかと思っています。 普通に生成する 一般的ですね、ですが外部に生成した後のフローの呼び出しなどを任せる必要があります。 今まであまり疑問に感じてこなかったのですが、以下の方法で生成手法を紐づけることができることに気がつきました。 // gist.github.com 副次的作用 この生成方法は、インスタンス生成メソッドに自身の情報変更を追加することが可能です。 つまるところ、Prefabに生成方法を… <p>少し走り書きになってしまっています、ご容赦ください。</p> <h3>内容</h3> <p>Unityを使用していると、必ずPrefabをInstantiateする行為を行うと思います。</p> <p>その際、以下のようなコードになるのではないかと思っています。</p> <p><script src="https://gist.github.com/83b9e789847c48e35aebaf348fcf3e98.js"> </script></p> <p><a href="https://gist.github.com/83b9e789847c48e35aebaf348fcf3e98">普通に生成する</a></p> <p> </p> <p>一般的ですね、ですが外部に生成した後のフローの呼び出しなどを任せる必要があります。</p> <p>今まであまり疑問に感じてこなかったのですが、以下の方法で生成手法を紐づけることができることに気がつきました。</p> <p> </p> <p> <script src="https://gist.github.com/PhantomIsland-kase/608ce520ac335f1b5660d83312588348.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/PhantomIsland-kase/608ce520ac335f1b5660d83312588348">gist.github.com</a></cite></p> <p> </p> <h3>副次的作用</h3> <p>この生成方法は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>生成メソッドに自身の情報変更を追加することが可能です。</p> <p>つまるところ、Prefabに生成方法を紐付けることが可能になります。</p> <p>これのおかげで生成に関するコードの堅牢性が上がりますね。</p> <p> </p> <p>ただ気をつけなくてはいけない部分として、Prefabを操作することになりますので</p> <p>AddComponentなどを使用するとPrefab自体も編集され、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>が追加されてしまいます。 </p> <p> </p> <p>初期化もついでに行う場合は、Serializeされていないデータの初期化などに留めておいた方が良さそうです。</p> <p> </p> <p>終わり。</p> yutakaseda3216 【Unity】開発の状況に合わせたUnityバージョンの選定基準について hatenablog://entry/17680117126988354307 2019-03-05T20:07:07+09:00 2019-03-05T20:07:07+09:00 Unityのバージョン、結局どれを使えばいいんだという声を聞いたのでまとめてみます。 開発状況別 + マイナーバージョンとパッチリリース含めて、Unity Editorやビルドプラットフォーム、新機能の安定度を基準にしています。 また、対象は1 ~ 2年以上かかる長期的な開発プロジェクトとしています。 開発開始時のバージョン選定 基本現状の最新版を選定しておいたほうがいい。 具体的に回避したいバグなどがない限りは、パッチリリースなどは考慮しなくて良い。 20xx.1.xが最新の場合 使いたい機能が現在 or 今後あれば使っていい、なければメジャーバージョンを前のものにしたほうがいい。 20xx… <p> </p> <p>Unityのバージョン、結局どれを使えばいいんだという声を聞いたのでまとめてみます。</p> <p>開発状況別 + マイナーバージョンとパッチリリース含めて、Unity Editorやビルドプラットフォーム、新機能の安定度を基準にしています。</p> <p>また、対象は1 ~ 2年以上かかる長期的な開発プロジェクトとしています。</p> <p> </p> <h3>開発開始時のバージョン選定</h3> <p>基本現状の最新版を選定しておいたほうがいい。</p> <p>具体的に回避したいバグなどがない限りは、パッチリリースなどは考慮しなくて良い。</p> <h4><br />20xx.1.xが最新の場合</h4> <p>使いたい機能が現在 or 今後あれば使っていい、なければメジャーバージョンを前のものにしたほうがいい。</p> <h4>20xx.2.xが最新の場合</h4> <p>とりあえずこれにするという選択も取れるレベル、後々4.x系にアップデートはすることになる。</p> <h4>20xx.3.xが最新の場合</h4> <p>とりあえずこれにしておこう。後々4.x系にアップデートはすることになる。</p> <h4>20xx.4.xが最新の場合</h4> <p>後でメジャーバージョンアップが必要になることが多いが、しないという選択もできる。</p> <p>最新が4.xならこれにしておこう。</p> <p> </p> <h3>開発がある程度進んだプロダクトのバージョンアップ基準</h3> <h4>20xx.1.x.fx or px</h4> <p>アップデートすると取り返しのつかないことになる。やめておけ。</p> <p>100%動かないと言ってもいい。</p> <h4>20xx.2.x.fx or px</h4> <p>凝った機能を使用している場合、バグfixなどで動作が変わっていることがある。</p> <p>動作が変わったと思ったらその次のバージョンでまた戻るとかも多い。</p> <p>正直辛いのでやめておいたほうがいい。</p> <h4>20xx.3.x.fx or px</h4> <p>いける、必要ならやってもいい。</p> <p>動かなくなる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>も多いと思うが、2.x -&gt; 3.xにするなど段階を踏めばまだ地雷は少ない。</p> <p>この辺りでパッチリリースを確認し、必要な修正が入っている場合はパッチリリースを使用することも検討して良い。</p> <h4>20xx.4.x.fx or px</h4> <p>もし同じメジャーバージョンの場合、4.xが出た時点で即座にアップデートしたほうがいい。</p> <p>前のマイナーバージョンのパッチで出た内容がまるまる取り込まれていることが多い。</p> <p>Unity的にいうとLTSなので、安定版。</p> <h3>開発が終わった後のプロダクトのバージョンアップ基準</h3> <p>そもそも基本バージョンアップはしないほうがいいが、やむをえぬ事情でやらないといけない時もある。</p> <h4>20xx.1.x.fx or px</h4> <p><strong>やめておけ。</strong></p> <h4>20xx.2.x.fx or px</h4> <p><strong>やめておけ。</strong></p> <h4>20xx.3.x.fx or px</h4> <p>段階を踏んでバージョンアップするならまだやってもいいが、基本はやめておいたほうがいい。</p> <h4>20xx.4.x.fx or px</h4> <p>・サポート端末が増える</p> <p>・何かのサポートが現行バージョンだと終わってしまう</p> <p>・処理が軽くなる</p> <p>などの中で必要な要件がいくつもあり、時間を割けるならやろう。</p> <p> </p> <h3>最後に</h3> <p>Unity の中の人、バージョンアップ大変だろうな。</p> <p>でも動作をマイナーバージョンアップなのにサイレントで変えるのはやめてください。</p> <p> </p> <p>後、皆IssueTrackerもちゃんと使ってバグレポ送ろうね。</p> yutakaseda3216 【備忘録】ゲームを発想するということ hatenablog://entry/98012380858485347 2019-02-05T14:36:01+09:00 2019-02-05T14:36:01+09:00 こんにちは、かせです。 最近は技術的なことは枯れた概念しかやっておらず、特に発信できることがないのでブログは止まりがちでごめんなさい。 色々な方と話をしてなんとなくゲームのコンセプトの決め方に2つのパターンがあるなあと思っていたのですが、やっと言語化できそうなのでさらっと書き留めておこうと思った次第です。 どっちもやってる人もいましたので一概には言い切れませんが、それぞれにメリットやデメリットが存在すると思うので上手くブレンドするといいなと思っています。 模倣と改善 8割の方がこちらでコンセプトを決めている気がします。 これは「既存のゲームデザインを模倣し、デザイン上の問題を目的に応じて改善し… <p> </p> <p>こんにちは、かせです。</p> <p> </p> <p>最近は技術的なことは枯れた概念しかやっておらず、特に発信できることがないのでブログは止まりがちでごめんなさい。</p> <p> </p> <p>色々な方と話をしてなんとなくゲームのコンセプトの決め方に2つのパターンがあるなあと思っていたのですが、やっと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%C0%B8%EC%B2%BD">言語化</a>できそうなのでさらっと書き留めておこうと思った次第です。</p> <p>どっちもやってる人もいましたので一概には言い切れませんが、それぞれにメリットやデメリットが存在すると思うので上手く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D6%A5%EC%A5%F3%A5%C9">ブレンド</a>するといいなと思っています。</p> <p> </p> <h4>模倣と改善</h4> <p>8割の方がこちらでコンセプトを決めている気がします。</p> <p>これは「既存の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%C7%A5%B6%A5%A4%A5%F3">ゲームデザイン</a>を模倣し、デザイン上の問題を目的に応じて改善しより昇華する」というものです。</p> <p>〜フォロワーというような言われ方をするゲームは、出発点はほぼここになっているのかなと思います。</p> <p>これは成功すればプレイヤーに受け入れられやすく、しかしぱっと見の目新しさなどは生み出しづらいものだと思っています。</p> <p> </p> <p>生み出しづらい、です。生み出せないとは言っていませんよ。</p> <p> </p> <h4>人間的な衝動のデフォルメ</h4> <p>残り2割くらいの方がこちらです。個人的な印象では、ヨコ○タ○ウさんはこのデザインがとても上手だと思います。</p> <p>これは「人間の感情の起伏を刺激する概念、事象をデフォルメしゲームに落とし込む」というものです。</p> <p>結構最近のゲームはこれは普通のゲームですよ〜という皮を被りながらこういう感情のデザインを奇抜にやってくる印象です。油断なりません。</p> <p> </p> <h4>広く普及したゲームのデザインの一部を解剖してみる</h4> <p>最近の普遍的な代表例で言えば、ダークソウルやPUBGですよねきっと。</p> <p>なのでその2つのゲームを上記に当てはめてみたいなと思います。</p> <p> </p> <h5>ダークソウル</h5> <p>死にゲー、というだけでは別に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DA%A5%E9%A5%F3%A5%AB%A1%BC">スペランカー</a>でも良いのですが。ダークソウルは「ソーシャルな死亡」をデザインしたゲームだと思います。</p> <p>血痕を調べると他のプレイヤーがどこでどのように死んだかがわかります。また、白霊として他のプレイヤーが死亡しないように手助けをしたり、赤霊として他のプレイヤーを死亡させることがゲームの本質的なデザインです。</p> <p> </p> <p>他の人が死ぬところを見たいって思ったことはありますか?僕はあります。</p> <p>だって見たことないですから。好奇心が湧きませんか?</p> <p> </p> <p>その度に少し仄暗い感情が芽生えるのですが、それをデフォルメして落とし込んだコンセプトが「ソーシャルな死亡」です。</p> <p>ダークソウルは「人間的な衝動のデフォルメ」を出発点として、既存の3Dゲームに落とし込んだゲームだと思っています。</p> <p> </p> <h5>PUBG</h5> <p>PUBGは圧倒的に「模倣と改善」に成功したゲームです。</p> <p>既存の<a class="keyword" href="http://d.hatena.ne.jp/keyword/FPS%A5%B2%A1%BC%A5%E0">FPSゲーム</a>はいわゆるチーム戦や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%C4%BF%CD%C0%EF">個人戦</a>が普遍的でしたが、そのどれもが負けると超絶ムカつくんですよね。</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/CoD">CoD</a>シリーズを300時間くらいプレイしていたのですが、とにかく負けると腹が立つんですよ。</p> <p>なぜかってゲームの目標が勝つことであり、全体のプレイヤーの総合勝率は必ず勝ちと負けが半々だからです。</p> <p> </p> <p>勝って負けて勝って負けて勝って負けて・・・ってなればいいんです、でもならないんですよね。</p> <p>上手い人が勝って勝って勝って勝って・・・下手な人は負けて負けて負けて負けて・・・です。</p> <p>そして負けた原因は「自分の腕前」あるいは「他のプレイヤーの腕前」にいきがちです。</p> <p> </p> <p>これをPUBGは改善しています、バトルロイヤル形式で100人中1人しか勝てない。</p> <p>つまり負けることが普通で、勝ったらとてつもなく嬉しいんです。</p> <p>負けることが普通って<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%C7%A5%B6%A5%A4%A5%F3">ゲームデザイン</a>が革命で、100人バトルロイヤルでは全体のプレイヤーの勝率は勝ちと負けが1:99なんです。</p> <p> </p> <p>ユーザーのストレスを著しく軽減している、これは「模倣と改善」の成功です。</p> <p> </p> <p>と思って書いていたんですが、ずっと昔に僕がシャドウバースでボコボコにされたちょもすさんが似たような記事をあげていました。</p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="対戦ゲームとランクマッチの呪い - chomoshのブログ" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fchomosh.hatenablog.com%2Fentry%2F2019%2F02%2F01%2F220556" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://chomosh.hatenablog.com/entry/2019/02/01/220556">chomosh.hatenablog.com</a></cite></p> <p> </p> <p>向こうは僕のことは覚えてもいないでしょうが、それこそが上記の記事で言われている不特定性の表れなのでちょっと笑顔になりました。</p> <p> </p> <h4>ゲームを発想するということ</h4> <p>ゲームの発想をパターン化して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%C0%B8%EC%B2%BD">言語化</a>してみましたが、別にこれに限らずカイヨワの遊びがどうちゃらとか色々ありますね。</p> <p> </p> <p>個人的には理論があれば道は間違えづらいとは思うので勉強するべきだと思いますが、「人間的な感情をデフォルメし、他人の感情をデザインし、デザイン上の問題を解決することで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%C7%A5%B6%A5%A4%A5%F3">ゲームデザイン</a>がより昇華される」という一連の文化的なプロセスが途切れないようにすることだけは意識したいですね。</p> <p> </p> <p>これこそが文化を生み出して紡ぐクリエイティブな人種のあるべき姿だと思っています。</p> <p> </p> <p> </p> <p>ポエムでした、おしまい。</p> yutakaseda3216 【雑記】デジゲー博2018で遊んだゲームの感想 hatenablog://entry/10257846132665423703 2018-11-07T11:35:59+09:00 2018-11-07T11:35:59+09:00 デジゲー博 デジゲー博 | 同人&インディーゲームオンリー展示・即売会 とても素晴らしいイベントで、2016年から毎年サークル参加をさせていただいてます。 主催の江崎さんのインタビュー記事はこちら www.gamecast-blog.com 国内のイベントで一番好きです。 今年は2スペースでサークル参加をさせていただいたのですがその話は置いておき、時間を無理やり空けて試遊しに行ったゲーム(少ない)の感想を書いておこうかなと思います。 東方3Dダンジョン - Rabbit Tail Works www.rabbittailworks.com 東方Projectの二次創作ゲームで、ゲームエンジンを… <p> </p> <h3>デジゲー博</h3> <p><a href="http://digigame-expo.org/">デジゲー博 | 同人&インディーゲームオンリー展示・即売会</a></p> <p> </p> <p>とても素晴らしいイベントで、2016年から毎年サークル参加をさせていただいてます。</p> <p> </p> <p>主催の江崎さんのインタビュー記事はこちら</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="デジゲー博主催、江崎望さんインタビュー「同人・インディーゲームに上も下もない。全ての開発者がフラットに参加できる場所を作りたい」" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fwww.gamecast-blog.com%2Farchives%2F65929407.html" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://www.gamecast-blog.com/archives/65929407.html">www.gamecast-blog.com</a></cite></p> <p> </p> <p>国内のイベントで一番好きです。</p> <p> </p> <p>今年は2スペースでサークル参加をさせていただいたのですがその話は置いておき、時間を無理やり空けて試遊しに行ったゲーム(少ない)の感想を書いておこうかなと思います。</p> <p> </p> <h4>東方3Dダンジョン - Rabbit Tail Works</h4> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="東方3Dダンジョン" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fwww.rabbittailworks.com%2Ftoho3ddungeon.html" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://www.rabbittailworks.com/toho3ddungeon.html">www.rabbittailworks.com</a></cite></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%CA%FDProject">東方Project</a>の二次創作ゲームで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%A8%A5%F3%A5%B8%A5%F3">ゲームエンジン</a>を使わない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EB%A5%B9%A5%AF%A5%E9%A5%C3%A5%C1">フルスクラッチ</a>の3Dアクションゲーム。</p> <p>随所に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%FE%A4%CE%A5%AA%A5%AB%A5%EA%A5%CA">時のオカリナ</a>リスペクトの演出や機能があり、試遊しててフフッとなる箇所が多くて楽しい。</p> <p> </p> <p>主人公は幻想郷に迷い込んだ一般人で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CE%EE%CC%B4">霊夢</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CB%E2%CD%FD%BA%BB">魔理沙</a>の助けを借りながら幻想郷から脱出する・・・というストーリー。</p> <p>試遊版はチルノに会う直前くらいまで遊べるようになっていた。</p> <p> </p> <p>足場に乗ってジャンプすると足場に置いていかれず、ちゃんと自分が足場に沿って移動していたりしていてちゃんと作り込んでる・・・ってなった。</p> <p><span style="text-decoration: underline;">あと、看板が切れる。最高。</span></p> <p> </p> <p>完成品の頒布もあるみたい、今回買えなかったのでどこかで見かけたら手に入れたい。</p> <p> </p> <h4>音ハメ(仮) - OY旅団</h4> <p><a href="https://oy-brigade.github.io/otohame-kari/">音ハメ (仮) | OY旅団</a></p> <p> </p> <p>リズムに乗りながら攻撃、ジャンプ、特殊技、前進、後退のコマンドを入力し、お互いに攻撃を当てあう音楽対戦ゲーム。</p> <p> </p> <p>暗殺者っぽい男、可愛い女の子、マヨネーズの擬人化の3キャ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%AF">ラク</a>ターが選択できたので、可愛い女の子を使おうとしてマヨネーズの擬人化を"間違えて"選んでしまった。</p> <p>間違えちゃったから仕方ないな、うん。</p> <p> </p> <p>マヨネーズの擬人化は特殊技が使えないらしいと説明を受けたときに、人は深く考えずに破滅する生き物だと思った。</p> <p> </p> <p>「後退して相手の攻撃を避けた後、前進して攻撃」などの動きのパターンを覚えつつ、相手のやりそうな行動を予測して行動を組み立てるのがとても面白かった。</p> <p> </p> <p>開発者の人と対戦したところ、1ポイント差で負けてしまったけど、ポイントがどう計算されているのかちょっと分からなかった悲しい。</p> <p> </p> <p>リンクからダウンロードできるので対戦してみよう。</p> <p> </p> <h4>地獄調査官 樹神妖子 (コダマヨーコ) - NOMANA INTERACTIVE</h4> <p><a href="https://nomana.itch.io/yoko">YOKO : Inquisitor of Hell(地獄調査官 樹神妖子) by NOMANA INTERACTIVE</a></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B5%FE%A5%B2%A1%BC%A5%E0%A5%B7%A5%E7%A5%A6">東京ゲームショウ</a>2018でも出展されていた色塗り陣取り<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A5%A4%A5%F3%A5%B9%A5%C6%A5%A3%A5%C3%A5%AF">ツインスティック</a>シューター。</p> <p> </p> <p>敵の攻撃や移動で徐々に地面に色が塗られ、その上にプレイヤーが乗ってしまうと呪いゲージが上がってしまい、呪いゲージが最大になるとゲームオーバーになるとか。</p> <p>プレイヤーが弾を撃つと着弾地点の周囲が自分の色になり、呪いゲージも徐々に減少する?(うろ覚え)らしいので立ち回りが大事っぽい。</p> <p> </p> <p>ランダム生成されるダンジョンを探索するタイプのゲーム進行のようなので、乗ってくるゲームの要素によっては<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%A2%A5%D6%A5%ED">ディアブロ</a>ばりの廃ゲーに変貌しそうでワクワクする。</p> <p> </p> <p>ゲーム性が新しくてとってもよいので完成が楽しみ。</p> <p> </p> <h4>Link: The Unleashed <a class="keyword" href="http://d.hatena.ne.jp/keyword/Nexus">Nexus</a> Restructured Haven(Link:RH) - Reminisce</h4> <p>りんく じ あんりーしゅど ねくさす りすとらくちゅあーど へいぶん</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Link: The Unleashed Nexus" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.reminiscedev.com%2F" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://www.reminiscedev.com/">www.reminiscedev.com</a></cite></p> <p> </p> <p>知り合いのSigさんが開発しているゲーム、Link:RHの最新版を展示するということで<span style="text-decoration: line-through;">壊しに</span>遊びに行った。</p> <p> </p> <p>ゲームスタートしたら新しい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%C3%A5%C8%A5%B7%A1%BC">カットシー</a>ンが再生されて、新演出でお出迎えされた。</p> <p>キャ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%AF">ラク</a>ターのモデル、モーション、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%C3%A5%C8%A5%B7%A1%BC">カットシー</a>ン、エフェクトが過去バージョンより洗練された印象になっていて、オヒトリデツクラレタンデスカ、ホントウニ?ワーオって感じ。</p> <p> </p> <p>一番気持ちよかったのが、敵を踏みつけたときに次の敵(次の目的地)に自動でカメラが向くので、迷わずにサクサク進められたこと。</p> <p>前は道に迷っちゃったことが何回かあったけど、あまり考えずに気持ちよくクリアまで進められた。</p> <p> </p> <p>プレイヤーの周りに展開してるエフェクトに空を飛ぶためのスラスターゲージの残量が表示されるようになっていたり、細かな演出への気配りがすごい。</p> <p> </p> <p>SigさんはたまにFaye/Sleepwalker(今僕がサークルで作っているゲーム)にスコスコにされるって言ってくるんですが、毎回僕もスコスコにされている。</p> <p>早く新トレイラーとか作って反撃したい。</p> <p> </p> <h3>遊んでないけど気になったゲーム</h3> <p>今回は本当に少数しかできなかったけど、見て回ったときに面白そうだなと思ったゲームを2つ、備忘録代わりに書いておく。</p> <p> </p> <h4>Monaka's Sugar High Nightmare - nokturnal studioz</h4> <p><a href="https://slimeman.itch.io/sugar">Monaka's Sugar High Nightmare by はちのす(Kei Kono)</a></p> <p> </p> <p>SOULLOGUE、BATTLLOONなどのゲームに携わっているはちのすさんが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A5%A4%A5%C3%A5%BF%A1%BC">ツイッター</a>で「なんかゲーム作りたい」から始まったらしいプロジェクト</p> <p>既に完成しているのでは?三ヶ月くらい?で作ったらしい。</p> <p>ゾンビの女の子が噛み付くのがフェチズムを感じるのでよい。</p> <p> </p> <h4>CisLugI(シスラギ) - NextVillage</h4> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="CisLugI|シスラギ|NextVillage" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fnextvillage.sakura.ne.jp%2F" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://nextvillage.sakura.ne.jp/">nextvillage.sakura.ne.jp</a></cite></p> <p> </p> <p>テレビCM流してたのここだった気がする、間違いかな。</p> <p>綺麗な画面だったので非常にきになる。実は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EB%A5%B9%A5%AF%A5%E9%A5%C3%A5%C1">フルスクラッチ</a>らしい?</p> <p> </p> <h3>最後に</h3> <p>他にも面白そうなゲームたくさんあった。</p> <p>「デモリッション<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%DC%A5%C3%A5%C4">ロボッツ</a> K・K」とか、「RYSTEL」とか名前覚えてないコンボゲーっぽい2Dアクションとか。</p> <p>宝箱か?また来年、僕は新作を引っさげて行く(強気)</p> <p> </p> <p>デジゲー博はいいぞ。</p> <p> </p> yutakaseda3216 【備忘録】Faye/Sleepwalkerの開発環境とサークルの運営について hatenablog://entry/10257846132656328474 2018-10-19T13:10:28+09:00 2018-10-19T13:10:28+09:00 最近ブログ書いてなかったので、サークルで開発する際に必要だった諸々の備忘録を書きます。 未来の自分と、もしかしたら誰かの参考になるかも。 開発環境・クライアント ゲームエンジン Unity 5.6 -> Unity 2017.1.1 -> Unity 2017.4.8f1 2017へ移行した理由として、Timeline機能とPostProcessingStackが使用できるのが割と決め手になりました。 LTS版のUnity 2017.4.x系から動かす気はもうありません。 Version Control System(VCS) git + git LFS 3Dゲームは大容量のバイナリファイルを… <p>最近ブログ書いてなかったので、サークルで開発する際に必要だった諸々の備忘録を書きます。</p> <p>未来の自分と、もしかしたら誰かの参考になるかも。</p> <p> </p> <h4>開発環境・クライアント</h4> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%A8%A5%F3%A5%B8%A5%F3">ゲームエンジン</a></h5> <p>Unity 5.6 -&gt; Unity 2017.1.1 -&gt; Unity 2017.4.8f1</p> <p>2017へ移行した理由として、Timeline機能とPostProcessingStackが使用できるのが割と決め手になりました。</p> <p>LTS版のUnity 2017.4.x系から動かす気はもうありません。</p> <h5>Version Control System(<a class="keyword" href="http://d.hatena.ne.jp/keyword/VCS">VCS</a>)</h5> <p>git + git <a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a></p> <p>3Dゲームは大容量のバイナリファイルを扱うので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>はほぼ必須です。</p> <p>特にバイナリファイルのgitのログは容量を無尽蔵に食い尽くしていきます。</p> <p> </p> <p>クライアントは<a class="keyword" href="http://d.hatena.ne.jp/keyword/bash">bash</a>を使っていたり、SourceTreeを使っていたり、人によってまちまちです。</p> <p>僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/bash">bash</a>を使って<a class="keyword" href="http://d.hatena.ne.jp/keyword/CUI">CUI</a>でぽちぽちしています。</p> <h5>AdobeXD,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Photoshop">Photoshop</a>,Illustlator</h5> <p>UIアーティストの方が使用しています。AdobeXDは優れたプロトタイピングツールなので便利です。</p> <p>特に説明は不要</p> <h4>開発環境・サービス</h4> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a></h5> <p>有料アカウント + <a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>用データパックで月1700円ほど</p> <p>プライベー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%EA%A5%DD%A5%B8">トリポジ</a>トリで開発をしています。</p> <h5>Trello</h5> <p>タスク管理はこちらで、TodoボードとStoryボードの二種類を作成し</p> <p>Todoボードにタスクをストック、毎月行うタスクをStoryボードで管理しています。</p> <p>・Storyボード</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20181019124341p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20181019/20181019124341.png" alt="f:id:yutakaseda3216:20181019124341p:plain" /></p> <p>・ToDoボード</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20181019124336p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20181019/20181019124336.png" alt="f:id:yutakaseda3216:20181019124336p:plain" /></p> <p>基本<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%E9%A5%E0">スクラム</a>の手法に則り、長いですが一ヶ月でスプリントを回しています。</p> <h5>Slack</h5> <p>サークル内でのコミュニケーションや開発進捗確認を行うためのチャットツールとして。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a>と連携し、pushされた際の通知を受け取っています。また、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%A5%AB%A5%EC%A5%F3%A5%C0%A1%BC">Googleカレンダー</a>での期日通知もついでにやってます。</p> <p>基本的にチャンネルは全てprivateにして招待するチャンネルを選別することで、外注の方をSlackに招待した際にも困らないようにしています。</p> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Drive">Google Drive</a>,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Calender,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Groups,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Gmail">Gmail</a></h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>系サービス色々</p> <p>・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Drive">Google Drive</a>にてデータ共有</p> <p>・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Calenderで各自のスケジュールとサークル全体のスケジュール管理</p> <p>・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Groupsでサークルメン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC">バー</a>のアカウントを一括管理</p> <p>・<a class="keyword" href="http://d.hatena.ne.jp/keyword/Gmail">Gmail</a>は言わずもがな。</p> <p>特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Groupsでのメン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC">バー</a>アカウントの管理は、カレンダーの共有や全体スケジュールの管理で便利ですのでオススメします。</p> <h4>開発サイクル</h4> <p>月に1回の定例会議を行なっています。</p> <p>毎月の共有事項話し合いやゲームプレイ、改善案出し合いからイベント参加そのほか議論タスク管理など、月の始めに行っています。</p> <p>2週間に1回の時期もありましたが、共有事項が少なくタスクの進捗もそれほどないため、会議がダレ気味になってしまい今のペースになりました。</p> <p>現在はよく回っています。</p> <p> </p> <p>また、イベント参加後には必ず<a class="keyword" href="http://d.hatena.ne.jp/keyword/KPT">KPT</a>形式での反省会を行なっています。</p> <p>これは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DD%A5%B9%A5%C8%A5%A4%A5%C3%A5%C8">ポストイット</a>で</p> <p>Keep(継続していくべきよかったこと)</p> <p>Problem(改善するべき問題)</p> <p>Try(問題を踏まえ改善していく方法)</p> <p>を壁に貼って出し合い、問題を明確にし解決していく手法です。これを導入することで全員の当事者感 &lt;- これ大事 が生まれました。とても良いです。</p> <h4>金銭管理</h4> <p>金銭で揉めたくなかったので、責任者を僕以外にし、全てその人の管轄で行なってもらっています。</p> <p>僕以外に責任を持ってもらった理由は「権力の分散」です。一人が権力を持ちすぎていいことは一つもありません。</p> <p>毎月の支出、収入を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%D7%A5%EC%A5%C3%A5%C9%A5%B7%A1%BC%A5%C8">スプレッドシート</a>でまとめてもらい定例会議で共有してもらっています。</p> <p>また、アセット購入などは全員で議論した上で、その人に承認してもらい初めて購入することができるようにしました。</p> <h4>タスク配分について</h4> <p>基本的に機能ごとに担当者を決め、敵なら**さん、UIなら**さん、という形で意図的に属人化させています。</p> <p>サークルでの作業は全て本業の傍らになりますので、モチベーションを持ってもらう必要があります。</p> <p>美味しいところは自分でやりたくなりますが、機能を全て任せてしまうことで当事者感を持ってもらい、また全員に均等に作業が行き渡るようにしています。</p> <p> </p> <p>もちろん、設計や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%B7%A5%E7%A5%F3">ディレクション</a>などはゲームデザイナーの僕が行なっている上での話です。</p> <p>これをやらなかったせいで、僕が全てを握ってしまい「俺いらないんじゃないか」と面と向かって言われ一度サークル崩壊間際になったことがあります。</p> <h5> </h5> <h4>まとめ</h4> <p>他にもあると思うんですが、備忘録なので思い出したら追記していこうと思います。</p> <p>サークルの運営とゲーム開発って両立させるの難しいと思うんですよね、その点会社ってよくできてます。</p> <p>社長とディレクターは分けるべきだなと常々思いますし、個々人を見て適切な対応をするのはとても難しいです。</p> <p> </p> <p>現在のサークルメン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC">バー</a>は全員、技術はもちろん<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BF%CD%B4%D6%C0%AD">人間性</a>自体がとても素晴らしい人達で、いつも助けられてばかりです。</p> <p>でも助けられることが少なくなるのはレッドシグナルだと思うので、今の状態はそれなりに健全な方向に向かっているんだろうなと思ってます。</p> <p>多人数をまとめるなら色々気を使いましょう。</p> <p> </p> <p>終わり。</p> yutakaseda3216 【Unity】複雑なアニメーション遷移を制御するAnimatorの作り方 hatenablog://entry/8599973812327928214 2017-12-19T13:13:11+09:00 2017-12-19T13:13:11+09:00 昔こんな記事を書きました。 yutakaseda3216.hatenablog.com さらに、最近Gotanda.unity - connpass という集まりでもAnimatorについてのLTを行いました。 ここらへんで、皆一度は悩むであろうAnimatorのそれなりにマシな作り方、設計の仕方をまとめていこうと思った次第です。 Animatorの矢印が多くて困っている、どういう指標で作ればわからない という方への手助けとなれば幸いです 既知の手法でAnimatorを作った際の問題点 まず、既知の手法でAnimatorを作るとこういった形になると思います 1つ1つAnimatorのステートを… <p> </p> <p>昔こんな記事を書きました。</p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="UnityのAnimatorでアニメーション遷移するときの自分なりの解 - かせノート。" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fyutakaseda3216.hatenablog.com%2Fentry%2F2016%2F08%2F19%2F112114" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2016/08/19/112114">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p>さらに、最近<a href="https://gotanda-unity.connpass.com/">Gotanda.unity - connpass</a> という集まりでもAnimatorについてのLTを行いました。</p> <p> </p> <p>ここらへんで、皆一度は悩むであろうAnimatorのそれなりにマシな作り方、設計の仕方をまとめていこうと思った次第です。</p> <p> </p> <p>Animatorの矢印が多くて困っている、どういう指標で作ればわからない</p> <p>という方への手助けとなれば幸いです</p> <p> </p> <h3>既知の手法でAnimatorを作った際の問題点</h3> <p> </p> <p>まず、既知の手法でAnimatorを作るとこういった形になると思います</p> <p> </p> <p><a href="https://docs.unity3d.com/jp/540/uploads/Main/MecanimAnimatorControllerWindow.png" class="http-image" target="_blank"><img class="http-image" src="https://docs.unity3d.com/jp/540/uploads/Main/MecanimAnimatorControllerWindow.png" alt="https://docs.unity3d.com/jp/540/uploads/Main/MecanimAnimatorControllerWindow.png" /></a></p> <p> </p> <p>1つ1つAnimatorのステートを作り、それらを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>で繋ぐ作り方です</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>の制御にはそれぞれboolやTriggerといったパラメータを用意し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>でAnimator.SetBool()などを呼び出す...</p> <p> </p> <p> </p> <p>ありがちですね</p> <p> </p> <p>UIなどに使用するシンプルなアニメーションであれば、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BE%E5%B5%AD">上記</a>手法でも良いかと思います</p> <p> </p> <p>しかし、キャラクターの制御などにこれをそのまま当てはめてしまうとこのようになっていくと思います</p> <p> </p> <p><a href="https://forum.unity.com/attachments/all-animations-small-jpg.67588/" class="http-image" target="_blank"><img class="http-image" src="https://forum.unity.com/attachments/all-animations-small-jpg.67588/" alt="https://forum.unity.com/attachments/all-animations-small-jpg.67588/" /></a></p> <p> </p> <p>これは極端な例ですが、矢印とパラメータが量産され視認性が悪くなっていきます</p> <p> </p> <p>視認性の悪さを改善できる、<span style="color: #d32f2f;">サブステートマシン</span>という機能が存在します</p> <p> </p> <p><a href="https://gametukurikata.com/wp-content/uploads/img/substate2.png" class="http-image" target="_blank"><img class="http-image" src="https://gametukurikata.com/wp-content/uploads/img/substate2.png" alt="https://gametukurikata.com/wp-content/uploads/img/substate2.png" /></a></p> <p> </p> <p>サブステートマシンとは、複数のステートをまとめておくことのできる機能です</p> <p> </p> <p>詳細な説明はこちらの方が詳しく載っていますので割愛します</p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【Unity】Animatorのスパゲティなステートマシンを整理する - テラシュールブログ" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Ftsubakit1.hateblo.jp%2Fentry%2F2015%2F12%2F21%2F031441" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://tsubakit1.hateblo.jp/entry/2015/12/21/031441">tsubakit1.hateblo.jp</a></cite></p> <p> </p> <p>サブステートマシンは良いグルーピングの手法ではありますが、この手法ではパラメータが量産されることを防止できません</p> <p> </p> <p>また、グルーピングされた結果サブステートマシンの中の特定のステートから、他のサブステートマシンの特定のステートへ直接遷移する</p> <p>などの手法は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>では取りづらくなります</p> <p> </p> <p>つまるところ、根本的な解決にはなっていません</p> <p> </p> <p> </p> <h3>必要な要件について</h3> <p> </p> <p>現在開発している3Dアクションゲーム、SLEEPWALKERでは</p> <ul> <li>大量にあるステートの全てが自由に遷移を組むことができること</li> <li>ステートの追加、組み替えが容易であること</li> <li>時間に応じたモーションブレンディング設定</li> <li>時間に応じたエフェクト設定、etc</li> </ul> <p>が必要でした</p> <p>いろいろと試行錯誤し、このような非常にスムースな遷移を実現できました</p> <p> </p> <p><iframe src="https://www.youtube.com/embed/2l9Zcw97nuw?feature=oembed" width="480" height="270" frameborder="0" allowfullscreen=""></iframe><cite class="hatena-citation"><a href="https://youtu.be/2l9Zcw97nuw">youtu.be</a></cite></p> <p> </p> <p> </p> <h3>具体的な設計、実装について</h3> <h4>Animator部分</h4> <p>まず、Animator自体はこのようになっています</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20171219123349p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20171219/20171219123349.png" alt="f:id:yutakaseda3216:20171219123349p:plain" /></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>、パラメータは一切ありません</p> <p>デフォルトのステートはIdle(待機)モーションになるように設定してあり、AnyStateやExitなどの機能も使用していません</p> <p> </p> <p>遷移は全てAnimator.CrossFadeInFixedTime()を使用しています</p> <p>これについてはこちらをご覧ください</p> <p> </p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="UnityのAnimatorでアニメーション遷移するときの自分なりの解 - かせノート。" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fyutakaseda3216.hatenablog.com%2Fentry%2F2016%2F08%2F19%2F112114" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2016/08/19/112114">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p> </p> <h4>遷移の方法について</h4> <p>遷移は<span style="color: #d32f2f;">StateMachineBehaviour</span>を継承した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を全てのステートに付け、制御を行っています</p> <p> </p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Unity - スクリプトリファレンス: StateMachineBehaviour" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.unity3d.com%2Fjp%2F540%2FScriptReference%2FStateMachineBehaviour.html" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.html">docs.unity3d.com</a></cite></p> <p> </p> <p>StateMachineBehaviourを継承することで、現在のステートのNormalizedTime(アニメーション経過時間)を取ることができるため</p> <p> </p> <p>経過時間に合わせた処理を行うことができるようになります</p> <p> </p> <p>まず基底クラスを作成し、NormalizedTimeなどを取得しやすくしました</p> <p><span style="color: #d32f2f;">かなりレガシーコードです、整理もしてません。Rxを使用しているのと、TODOとか書いてあるので、設計自体はあまり参考にしないでください</span></p> <p> </p> <p> <script src="https://gist.github.com/PhantomIsland-kase/f1d8f53e4f021c8c070cec2581687de1.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/PhantomIsland-kase/f1d8f53e4f021c8c070cec2581687de1">gist.github.com</a></cite></p> <p> </p> <p>ResetTime()メソッドは、<span style="color: #d32f2f;">NormalizedTimeはステートにいる限り加算され続ける仕様のため</span>、ループ設定をした際にNormalizedTimeが0.0f~1.0fで見れるようにtimeを初期化する処理です</p> <p> </p> <p>気をつけないとループするアニメーションの際に設定したエフェクトなどが再生されなくなるので気をつけましょう</p> <p> </p> <p> </p> <p>この基底を使いこのような設定を行うことのできる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ができました</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>設定<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a></p> <h5><img class="hatena-fotolife" title="f:id:yutakaseda3216:20171219124202p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20171219/20171219124202.png" alt="f:id:yutakaseda3216:20171219124202p:plain" /></h5> <p> </p> <p>遷移が可能なステートの<a class="keyword" href="http://d.hatena.ne.jp/keyword/enum">enum</a>を定義し、遷移優先度、遷移可能時間などを設定しています</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>もそのまま乗せておきます、こちらもかなりレガシーなコードなのであまり参考にはせず、ニュアンスだけの理解にとどめてもらえると嬉しいです</p> <p> </p> <p> <script src="https://gist.github.com/PhantomIsland-kase/3a20295fcd35870fe12da38f55d8e95e.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/PhantomIsland-kase/3a20295fcd35870fe12da38f55d8e95e">gist.github.com</a></cite></p> <p> </p> <p><span style="font-size: 80%;">今見てもシングルトン経由したりしてやべえコードだ・・・</span></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BE%E5%B5%AD">上記</a>のようにAnimatorでアニメーション時間に関連する処理を書いていますが</p> <p>AnimatorのStateと連動したStateMachineを作成し、Animatorの外側でゲームに関連する処理を書いています</p> <p> </p> <p> <script src="https://gist.github.com/PhantomIsland-kase/c7c61020f6c3c63d75202f62b4a56c3f.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/PhantomIsland-kase/c7c61020f6c3c63d75202f62b4a56c3f">gist.github.com</a></cite></p> <p> </p> <h4>アニメーション時間に応じたその他の処理</h4> <p> </p> <p>攻撃判定発生<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a></p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20171219124243p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20171219/20171219124243.png" alt="f:id:yutakaseda3216:20171219124243p:plain" /></p> <p> </p> <p>こちらも時間軸で動作を定義しています</p> <p> </p> <p>SE再生<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a></p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20171219124314p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20171219/20171219124314.png" alt="f:id:yutakaseda3216:20171219124314p:plain" /></p> <p> </p> <p>ループ設定などもできるようにしてあります </p> <p> </p> <p> </p> <h3>まとめ</h3> <p>というわけで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>設定をStateMachineBehaviourの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>に寄せ、アニメーション時間が必要な処理もまとめてぶちこんでいます</p> <p> </p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>設定を作っていくのに比べて</p> <ul> <li>パラメータがない</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B8%A5%B7%A5%E7%A5%F3">トランジション</a>設定がない</li> </ul> <p>ので視認性、拡張性に優れます</p> <p> </p> <p>また、Unity2017で追加されたPlayableを使用した完全<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ベースの手法も存在しますが</p> <ul> <li>Animatorでステートの制御をぽちぽち作れること</li> <li>ステートをビジュアル化しておけること</li> <li>コード量の少なさ</li> </ul> <p>で優位です</p> <p> </p> <p>もちろん適材適所ですが、1つの指標になれば幸いです</p> <p> </p> <p> </p> <h4>宣伝</h4> <p>現在開発中のゲーム、SLEEPWALKERの体験版がweb公開されました!</p> <p>よろしければぜひプレイしてみてください</p> <p> </p> <p><a href="https://www.studiophantomisland.com/">https://www.studiophantomisland.com/</a></p> yutakaseda3216 【Unity】OnPostProcessAllAssetsを使う時に特定の方法で無限ループする hatenablog://entry/8599973812303794787 2017-10-02T16:04:26+09:00 2017-10-02T16:04:26+09:00 OnPostProcessAllAssetsについて docs.unity3d.com このクラスを継承したEditorクラスは、OnPostProcessAllAssetsメソッドを定義することでアセットインポート時に処理をフックすることができる。 ScriptableObjectやなんやに自動登録したり、asset判別して何かする時によく使う。 無限ループする原因 OnPostProcessAllAssetsを定義したクラスが2つ以上ある そのどちらも、処理の中でAssetDataBase.StartAssetEditing()とAssetDataBase.StopAssetEditing… <p> </p> <h3>OnPostProcessAllAssetsについて</h3> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Unity - スクリプトリファレンス: AssetPostprocessor" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.unity3d.com%2Fja%2F540%2FScriptReference%2FAssetPostprocessor.html" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://docs.unity3d.com/ja/540/ScriptReference/AssetPostprocessor.html">docs.unity3d.com</a></cite></p> <p> </p> <p>このクラスを継承したEditorクラスは、OnPostProcessAllAssetsメソッドを定義することでアセットインポート時に処理をフックすることができる。</p> <p> </p> <p>ScriptableObjectやなんやに自動登録したり、asset判別して何かする時によく使う。</p> <p> </p> <h4>無限ループする原因</h4> <p> </p> <ol> <li>OnPostProcessAllAssetsを定義したクラスが<span style="color: #d32f2f;">2つ以上</span>ある</li> <li>そのどちらも、処理の中でAssetDataBase.StartAssetEditing()とAssetDataBase.StopAssetEditing()を呼んでいる。</li> <li>どちらもAssetDataBase.Refresh()を呼んでいる。</li> </ol> <p> </p> <p>以上です。</p> <p> </p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Unity - スクリプトリファレンス: AssetDatabase" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.unity3d.com%2Fja%2F540%2FScriptReference%2FAssetDatabase.html" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://docs.unity3d.com/ja/540/ScriptReference/AssetDatabase.html">docs.unity3d.com</a></cite></p> <p> </p> <p> </p> <p>アセットインポート時に、さらにアセットをインポートする処理を書いてしまうとOnPostProcessAllAssetsをお互いに呼び合ってしまうので無限ループするっぽいです。</p> <p> </p> <p> </p> <h4>回避方法</h4> <p> </p> <ol> <li>OnPostProcessAllAssetsは引数に変更されたアセットのパスが入っているので、パスを使用し処理を行うべきか否かを判別する</li> <li>OnPostProcessAllAssetsを受け取るルートクラスを作成し、個別に受け取らない</li> </ol> <p> </p> <p> </p> <h4>最後に</h4> <p> </p> <p>回避はこれで可能、原因も多分あってる。</p> <p>ただどうにも釈然としないので、何かピンと来た方<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>までぜひご連絡ください。</p> <p> </p> yutakaseda3216 【Unity】Timelineで使用するPlayableAssetとPlayableBehaviourを参照を追加しながら作成するエディタ拡張 hatenablog://entry/8599973812301407142 2017-09-25T21:56:41+09:00 2017-09-25T21:56:41+09:00 リポジトリ github.com ここにプロジェクトとUnitypackageがあがってるのでダウンロードなりcloneなりをどうぞ 使い方 メニューに表示されているPhantomIsland -> Windowからエディタを開いてください。 設定できる項目は 使用するnamespace 変数の型、変数名、参照タイプ です 参照タイプはシーン上のオブジェクトはExposedReferenceを選択してください。 大体ExposedReferenceだと思います、多分・・・。 CreateScriptボタンを押すと、保存先と名前を指定するウィンドウが出るので設定して保存して下さい。 保存した名前… <p> </p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a></h3> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="PhantomIsland-kase/ScriptUtil" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2FPhantomIsland-kase%2FScriptUtil" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://github.com/PhantomIsland-kase/ScriptUtil">github.com</a></cite></p> <p> </p> <p>ここにプロジェクトとUnitypackageがあがってるのでダウンロードなりcloneなりをどうぞ</p> <p> </p> <p> </p> <h3>使い方</h3> <p> </p> <p>メニューに表示されているPhantomIsland -&gt; Windowからエディタを開いてください。</p> <p> </p> <p> </p> <p>設定できる項目は</p> <p> </p> <ul> <li>使用するnamespace</li> <li>変数の型、変数名、参照タイプ</li> </ul> <p>です</p> <p> </p> <p>参照タイプはシーン上のオブジェクトはExposedReferenceを選択してください。</p> <p>大体ExposedReferenceだと思います、多分・・・。</p> <p> </p> <p>CreateScriptボタンを押すと、保存先と名前を指定するウィンドウが出るので設定して保存して下さい。</p> <p> </p> <p>保存した名前の末尾に~Assetと~Behaviourという名前が付くので、~Playableという名前がよいかも。</p> <p> </p> <p>保存すると、設定した参照がすべて記入されており、PlayableAssetはいじる必要がなく、基本的にPlayableBehaviourにロジックを記述するだけでよくなっています。</p> <p> </p> <h3>最後に</h3> <p> </p> <p>まだまだTimelineは進化しそうなので、情報を追っていきますぞ。</p> yutakaseda3216 【C#】NSubstituteを使用してクラスをモックとして偽装する hatenablog://entry/8599973812299458662 2017-09-19T14:22:10+09:00 2017-09-19T14:51:00+09:00 NSubstituteとは? 定義されたinterfaceを使用して、クラスの振る舞いをモックとして定義することが出来るライブラリ interfaceに定義されているフィールドやメソッドの返す値や動作を一つずつ定義できるので、テストしたいクラスに渡すデータなどの偽装が可能 とにかく非常に便利で、使いやすく有用 入手はこちら github.com Unityで使用する際はUnity Test Tools を入手して、Pluginsの中にdllを入れると動作する https://www.assetstore.unity3d.com/jp/#!/content/13802 基本的に実機動作はしません… <p> </p> <h3>NSubstituteとは?</h3> <p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> </p> <p>定義されたinterfaceを使用して、クラスの振る舞いをモックとして定義することが出来るライブラリ</p> <p> </p> <p>interfaceに定義されているフィールドやメソッドの返す値や動作を一つずつ定義できるので、テストしたいクラスに渡すデータなどの偽装が可能</p> <p> </p> <p>とにかく非常に便利で、使いやすく有用</p> <p> </p> <p>入手はこちら</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="nsubstitute/NSubstitute" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fnsubstitute%2FNSubstitute" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://github.com/nsubstitute/NSubstitute">github.com</a></cite></p> <p> </p> <p> </p> <p>Unityで使用する際はUnity Test Tools を入手して、Pluginsの中にdllを入れると動作する</p> <p> </p> <p><a href="https://www.assetstore.unity3d.com/jp/#!/content/13802">https://www.assetstore.unity3d.com/jp/#!/content/13802</a></p> <p> </p> <p>基本的に実機動作はしません、UnityならEditor上のみで使用するようにしてください </p> <h3> </h3> <h3>簡単な使い方</h3> <p> </p> <p>クラスとフィールド、メソッドの動作を偽装した例</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/a0458df78ec0c6b7e635486acd660583.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/a0458df78ec0c6b7e635486acd660583">gist.github.com</a></cite></p> <p> </p> <p> </p> <p>割と簡単に定義できる</p> <p> </p> <p> </p> <h3>ちょっとした小技</h3> <p> </p> <p>メソッドの中で自身のフィールドを変更したい時などは、一度データをキャッシュするとよい</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/4bf51d03b2679099a0037978f555f2d8.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/4bf51d03b2679099a0037978f555f2d8">gist.github.com</a></cite></p> <p> </p> <p>直接フィールドを書き換えることはできないので、気をつけよう</p> <p> </p> <p> </p> <p>ある特定の機能だけ動作させたいけどデータがないよ〜という時はガンガン使っていこう</p> yutakaseda3216 ブログ名とかを変えました。 hatenablog://entry/8599973812296944313 2017-09-11T12:05:54+09:00 2017-09-11T12:05:54+09:00 ブログ名とか、中のデザインを一部変えました。 開発とかメモ -> かせの開発とかメモ。 -> かせノート。 <- New! 書くことはほとんど変わらないと思いますので、今後ともご愛読くだされば幸いでございます。 よろしくお願いします。 <p> </p> <p> </p> <p>ブログ名とか、中のデザインを一部変えました。</p> <p> </p> <p>開発とかメモ -&gt; かせの開発とかメモ。 -&gt; かせノート。 &lt;- <span style="color: #d32f2f;">New!</span></p> <p> </p> <p>書くことはほとんど変わらないと思いますので、今後ともご愛読くだされば幸いでございます。</p> <p> </p> <p>よろしくお願いします。</p> yutakaseda3216 【プログラミング】MVC,MVPを理解するためのレイヤーアーキテクチャ hatenablog://entry/8599973812284493991 2017-08-01T12:28:01+09:00 2017-08-01T12:28:01+09:00 少しだけ長いので、根気を持ってお読みください。 レイヤーアーキテクチャについて 言葉で表現すると 個々のオブジェクトの設計に依存しない、概念的な部分の設計思想 各機能の「置き場所」の定め方 あるいは、各機能の依存先を決める手段 責務を明確化する思想 この記事を読んでいるということは、MVPやMVCについては聞いたことがある、実践したことがある人は多そう 前提知識としてあると理解しやすい、かも 詳しく説明してくれている記事がありました qiita.com 引用 "レイヤアーキテクチャというのはアプリケーションを責務に応じたいくつかの層としてとらえる設計手法のことです。" 表面的にはまさにこの通り… <p> </p> <p>少しだけ長いので、根気を持ってお読みください。</p> <p> </p> <h3>レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>について</h3> <p> </p> <p>言葉で表現すると</p> <ul> <li>個々のオブジェクトの設計に依存しない、概念的な部分の設計思想</li> <li>各機能の「置き場所」の定め方</li> <li>あるいは、各機能の依存先を決める手段</li> <li><span style="color: #d32f2f;">責務を明確化する思想</span></li> </ul> <p> </p> <p>この記事を読んでいるということは、MVPや<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>については聞いたことがある、実践したことがある人は多そう</p> <p>前提知識としてあると理解しやすい、かも</p> <p> </p> <p> </p> <p>詳しく説明してくれている記事がありました</p> <p> </p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="中規模Web開発のためのMVC分割とレイヤアーキテクチャ - Qiita" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fqiita.com%2Fyuku_t%2Fitems%2F961194a5443b618a4cac%23%25E3%2583%25AC%25E3%2582%25A4%25E3%2583%25A4%25E3%2582%25A2%25E3%2583%25BC%25E3%2582%25AD%25E3%2583%2586%25E3%2582%25AF%25E3%2583%2581%25E3%2583%25A3" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://qiita.com/yuku_t/items/961194a5443b618a4cac#%E3%83%AC%E3%82%A4%E3%83%A4%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3">qiita.com</a></cite></p> <p> </p> <p>引用</p> <p>"レイヤ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>というのはアプリケーションを責務に応じたいくつかの層としてとらえる設計手法のことです。"</p> <p> </p> <p>表面的にはまさにこの通りですが、層という概念に当てはめてしまうのはいささか語弊があります</p> <p> </p> <p>この記事の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>の部分はすっ飛ばして(失礼ではありますが)レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の部分だけを読んでいただけると良いと思います</p> <p> </p> <p> </p> <p>今回伝えたいことは、プレゼンテーション層、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C9%A5%E1%A5%A4%A5%F3">ドメイン</a>層などで固定化されたレイヤーの話ではなく、<span style="color: #d32f2f;">必要な責務を考え、自身のアプリケーションに応じて必要なレイヤーを考え出すことをレイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の知識として定義したいという話です</span></p> <p> </p> <p> </p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の歴史</h3> <p> </p> <p>レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の理解のために、過去の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の歴史をまず振り返ってみます</p> <p> </p> <h4>オブジェクト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>の歴史</h4> <p> </p> <p>いわゆる、個々の機能の設計です、大まかに3つの進化がありました</p> <p> </p> <h5>goto statement programming</h5> <p><a href="https://ja.wikipedia.org/wiki/Goto%E6%96%87">goto文 - Wikipedia</a></p> <p> </p> <p>プログラムの要所要所にラベルを定義し、goto文を使用して指定したラベルに飛ぶことで、ロジックを全て縦に記述しながらも強引にモジュール化を図るプログラミング手法です</p> <p> </p> <p>あっちこっちに処理が飛び、人間の脳内キャッシュを膨大に使用するので今見ると非常に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%D1%A5%B2%A5%C3%A5%C6%A5%A3%A5%B3%A1%BC%A5%C9">スパゲッティコード</a>に見えるでしょう</p> <p> </p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Why the GOTO Statement Is Evil - Linux Digest" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fwww.linuxdigest.org%2Fblog%2F2012%2F06%2F14%2Fwhy-goto-statement-is-evil%2F" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://www.linuxdigest.org/blog/2012/06/14/why-goto-statement-is-evil/">www.linuxdigest.org</a></cite></p> <p> </p> <p>なぜgoto文が悪であるのかはこちらの記事を読むとわかりやすいと思います</p> <p> </p> <p> </p> <h5> structured programming</h5> <p><a href="https://ja.wikipedia.org/wiki/%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0">構造化プログラミング - Wikipedia</a></p> <p> </p> <p>構造化プログラミングのことです、<span style="color: #d32f2f;">かなり端折った説明をします</span>ので本来の意味合いを知りたいのであれば書籍などを購入すると良いと思います</p> <p> </p> <p>構造化プログラミングはgoto-lessとも呼ばれ、ロジックを上流(状態)、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BC%CE%AE">下流</a>(処理)に分けることで上流の状態に応じた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BC%CE%AE">下流</a>の処理を呼び出すという概念が生まれました</p> <p> </p> <p>しかし、処理を分割すればするほど上流の状態が増えることになり、完全なロジックの分離はほとんど不可能でした</p> <p> </p> <p>しかし、goto statementにはなかった、<span style="color: #d32f2f;">処理の記述に流れを作る</span>という点において、近代のプログラミング思想の根底に関わっています</p> <p> </p> <h5>object oriented programming</h5> <p><a href="https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0">オブジェクト指向プログラミング - Wikipedia</a></p> <p> </p> <p>皆大好き<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%D6%A5%B8%A5%A7%A5%AF%A5%C8%BB%D8%B8%FE">オブジェクト指向</a>です、もはや呪いと言っても過言ではなさそうです</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%D7%A5%BB%A5%EB%B2%BD">カプセル化</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DD%A5%EA%A5%E2%A1%BC%A5%D5%A5%A3%A5%BA%A5%E0">ポリモーフィズム</a>など様々な概念が存在しますが</p> <p> </p> <p>「<span style="color: #d32f2f;">データとロジックを一つのまとまり</span>として記述し、処理の関心を内側にのみ向け、処理に応じたメッセージを発行することで、他のオブジェクトの処理のトリガーとして<span style="color: #d32f2f;">影響</span>を与えつつ、その<span style="color: #d32f2f;">影響に関心を持たない</span>」</p> <p> </p> <p>という概念になるかと思います</p> <p> </p> <p>これを端的に表したものがオブジェクトという言葉であり、またクラスという機能として表現されているものです</p> <p> </p> <p>この概念を用いることで、structured programmingだけではなしえなかった<span style="color: #d32f2f;">ロジックの完全な分離が可能になりました</span></p> <p> </p> <p> </p> <h5>オブジェクト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>のまとめ</h5> <p>goto statement programmingで処理を記述するという行為を行い</p> <p>structured programmingで処理の流れの概念ができ</p> <p>object oriented programmingでロジックの分離を行った</p> <p> </p> <p> </p> <p>しかし、これでは処理の置き場所はオブジェクトで定義できましたが、<span style="color: #d32f2f;">オブジェクトの置き場所</span>が定義できていません</p> <p>ここからはオブジェクトのまとまりをレイヤーとして定義する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>についてです</p> <p> </p> <p> </p> <h4>多層<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a></h4> <p><a href="https://ja.wikipedia.org/wiki/%E5%A4%9A%E5%B1%A4%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3">多層アーキテクチャ - Wikipedia</a></p> <p> </p> <p>近代的な設計思想は多数ありますが、そこから多層<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>を抜粋します</p> <p> </p> <p> </p> <p>独立したモジュールとして層を定義し、差し替え、機能改善などを容易にすることが可能な設計思想です</p> <p> </p> <p>代表的なものとして三層<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>が存在します</p> <p> </p> <p> </p> <p>三層<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>は、Webアプリケーションが</p> <ul> <li>データベース</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DF%A5%C9%A5%EB%A5%A6%A5%A7%A5%A2">ミドルウェア</a>(インターフェース)</li> <li>ユーザー(ユーザー操作)</li> </ul> <p>という要素で構成されるようになった際に提唱された概念です</p> <p> </p> <p> </p> <p>データ、ロジック、プログラミング的な構成要素としては</p> <ul> <li>データベース・DB</li> <li>データベース操作のための<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a></li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B6%A1%BC%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A1%BC%A5%B9">ユーザーインターフェース</a></li> </ul> <p>の三種類が必要になります</p> <p> </p> <h5>データベース</h5> <p> </p> <p>データを保持、管理します</p> <p> </p> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a></h5> <p> </p> <p>ユーザー操作に応じた処理のロジック、及びデータベースの操作を記述し公開します</p> <p> </p> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B6%A1%BC%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A1%BC%A5%B9">ユーザーインターフェース</a></h5> <p> </p> <p>ユーザーの操作を検知し、操作に応じた処理を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a>に問い合わせます</p> <p>(<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を叩くということと同義です)</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a>の結果を使用して自身を更新します</p> <p> </p> <p> </p> <p>以上のように、各レイヤーに対して明確に責務が割り当てられており</p> <p>また、<span style="color: #d32f2f;">依存関係が単方向になっています</span></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B6%A1%BC%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A1%BC%A5%B9">ユーザーインターフェース</a> -&gt; <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a></p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a> -&gt; データベース</p> <p> </p> <p>データベースは自身以外を知りませんし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a>はデータベース以外知りません</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B6%A1%BC%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A1%BC%A5%B9">ユーザーインターフェース</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%B8%A5%CD%A5%B9%A5%ED%A5%B8%A5%C3%A5%AF">ビジネスロジック</a>以外知りません</p> <p> </p> <p> </p> <p>単方向ですね</p> <p> </p> <p>責務を明確化すると、その責務を果たすために必要な情報を持つレイヤーに対してのみ依存する形になるため、結果として関連するロジックを持つオブジェクトの凝集度が上がり、依存関係を簡潔に定義することができます</p> <p> </p> <p> </p> <h3>レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>のおさらい</h3> <p> </p> <ul> <li>個々のオブジェクトの設計に依存しない、概念的な部分の設計思想</li> <li>各機能の「置き場所」の定め方</li> <li>あるいは、各機能の依存先を決める手段</li> <li><span style="color: #d32f2f;">責務を明確化する思想</span></li> </ul> <p> </p> <p>です</p> <p>重要な部分は責務の明確化です</p> <p> </p> <p> </p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>,MVPとは一体なんなのか?</h3> <p> </p> <p>Model - View - Controller</p> <p> </p> <p>Model - View - Presenter</p> <p> </p> <p>さらにはMVVM,CleanArchitectureまで様々な概念が存在します</p> <p> </p> <p>これらはすべて、<span style="color: #d32f2f;">レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>に基づいた責務の割り当て方の一つの形</span>です</p> <p> </p> <h5>一般的に普及していると思われる<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>の例</h5> <p> </p> <p>Modelの責務</p> <ul> <li>データを管理する</li> <li>データを更新するためのロジックを公開する</li> <li>(必要であればサーバーと通信する)</li> <li>データの更新を通知する</li> </ul> <p> </p> <p>Viewの責務</p> <ul> <li>ユーザー操作を提供する</li> <li>Modelの通知、データを元に自身を公開する</li> </ul> <p> </p> <p>Controllerの責務</p> <ul> <li>ユーザー操作を監視する</li> <li>操作に対応したModelの更新ロジックを呼ぶ</li> </ul> <p> </p> <p> </p> <p>こういった形で責務が割り振られています</p> <p> </p> <p>MVPも同じく、責務が割り振られています、MVVMもCleanArchitectureも同じです</p> <p> </p> <p> </p> <p>こういった責務を捉える力を持つことで、<span style="color: #d32f2f;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>やMVPなどの既存のレイヤーに縛られない責務の洗い出し、割り振りが可能になります</span></p> <p> </p> <p> </p> <h4>例.<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>を、サーバーとの通信部分を踏まえて責務の割り振りを改善する</h4> <p> </p> <p>一般的な<a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>の責務は前述しましたが、Modelがサーバーと通信する場合、しない場合を踏まえて、サーバーと通信するという責務を切り出し、別のレイヤーとして定義します</p> <p> </p> <p>名前はServiceレイヤーとし、SMVCと定義します</p> <p> </p> <p> </p> <p>Serviceの責務</p> <ul> <li><span style="color: #d32f2f;">Modelを更新するためのロジックを公開する</span></li> <li><span style="color: #d32f2f;">Model更新のためのデータをサーバーから取得する</span></li> </ul> <p> </p> <p>Modelの責務</p> <ul> <li>データを管理する</li> <li>データを更新するためのロジックを公開する</li> <li><span style="color: #d32f2f;">データ更新の際に必要であればServiceのロジックを呼ぶ</span></li> <li>データの更新を通知する</li> </ul> <p> </p> <p>Viewの責務</p> <ul> <li>ユーザー操作を提供する</li> <li>Modelの通知、データを元に自身を公開する</li> </ul> <p> </p> <p>Controllerの責務</p> <ul> <li>ユーザー操作を監視する</li> <li>操作に対応したModelの更新ロジックを呼ぶ</li> </ul> <p> </p> <p> </p> <p>切り出しました</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MVC">MVC</a>にはないメリットとして</p> <p>このServiceレイヤーはサーバー側にのみ依存し、またローカル用のモックと差し替えることでローカル環境での更新も可能になりました</p> <p>結果、Modelはシンプルな記述のみになったと思います</p> <p> </p> <p>他にもあるかもしれません </p> <p> </p> <p> </p> <p>こういった形で設計を改善することもできます、参考になったでしょうか</p> <p> </p> <p> </p> <h3>まとめ</h3> <p> </p> <p>責務を洗い出し、責務の一つ一つをオブジェクトの集合体となるレイヤーに割り振ることを</p> <p> </p> <p><span style="color: #d32f2f;">レイヤー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a></span></p> <p> </p> <p>として定義し、広く理解され普及すると良いなと思います</p> <p> </p> <p> </p> <p>知識の部分は厳密には間違いがあるかもしれませんが、伝えたいことが伝わっていれば幸いですね</p> <p> </p> yutakaseda3216 【Unity】TestRunnerをbatchmodeで起動した際に謎xmlが吐き出されるバグ【NUnit】 hatenablog://entry/8599973812284258398 2017-07-31T18:12:06+09:00 2017-12-22T12:09:49+09:00 2017/12/22追記 Unity2017.3で治ったようです、よかった Unity5.6からなのかわからんのですけど、JenkinsのNUnit test result reportがコケまくるんですが、同じこと起きた人いないかな。。。— かせ (@YutaDevelop) 2017年7月31日 バージョン Unity5.6.2f1 ソース issuetracker.unity3d.com やりたかったこと Jenkins上でUnityTestRunnerをbatchmodeで起動して、吐き出されたxmlをNUnitPluginで解析 CI環境で自動テストを行いたかった 結果 上記Issu… <p> </p> <p> </p> <p> </p> <p><span style="color: #d32f2f;">2017/12/22追記</span></p> <p>Unity2017.3で治ったようです、よかった</p> <p> </p> <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Unity5.6からなのかわからんのですけど、Jenkinsの<a class="keyword" href="http://d.hatena.ne.jp/keyword/NUnit">NUnit</a> test result reportがコケまくるんですが、同じこと起きた人いないかな。。。</p>&mdash; かせ (@YutaDevelop) <a href="https://twitter.com/YutaDevelop/status/891927626092167169?ref_src=twsrc%5Etfw">2017年7月31日</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <h3>バージョン</h3> <p>Unity5.6.2f1</p> <p> </p> <p> </p> <h3>ソース</h3> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Unity IssueTracker - Running Unity in batchmode gives a result file with the wrong test type" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fissuetracker.unity3d.com%2Fissues%2Frunning-unity-in-batchmode-gives-a-result-file-with-the-wrong-test-type" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://issuetracker.unity3d.com/issues/running-unity-in-batchmode-gives-a-result-file-with-the-wrong-test-type">issuetracker.unity3d.com</a></cite></p> <p> </p> <p> </p> <h3>やりたかったこと</h3> <p>Jenkins上でUnityTestRunnerをbatchmodeで起動して、吐き出された<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>をNUnitPluginで解析</p> <p>CI環境で自動テストを行いたかった</p> <p> </p> <h3>結果</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BE%E5%B5%AD">上記</a>Issueのためできなかった</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>の吐き出される形式がTestSuiteのため、NUnitPluginがうまくパースしてくれない</p> <p> </p> <p>結果、ビルドがコケる</p> <p> </p> <h3>Unityさんへ</h3> <p>早く治して・・・</p> <p> </p> yutakaseda3216 【Unity】UniRxで独自オペレータを作る、Observableの拡張 hatenablog://entry/8599973812282902564 2017-07-26T17:47:11+09:00 2017-08-22T10:31:45+09:00 UniRx github.com いつもお世話になっています。 オペレータとは IObservable<T>の拡張メソッドとして用意されたストリームソースを加工するためのクラス オペレータはIObservable<T>を継承しているので、メソッドチェーンすることができます ざっくりふわふわとした説明は以上 作るもの オペレータの作成のためにはまず2種類のクラスと拡張メソッドを定義する必要があります 具体的には OperatorObservableBase<T>を継承したストリームをSubscribeするクラス OperatorObserverBase<TSource,TResult>を継承した… <h3>UniRx</h3> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="neuecc/UniRx" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fneuecc%2FUniRx" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://github.com/neuecc/UniRx">github.com</a></cite></p> <p> </p> <p>いつもお世話になっています。</p> <p> </p> <h3>オペレータとは</h3> <p>IObservable&lt;T&gt;の拡張メソッドとして用意されたストリームソースを加工するためのクラス</p> <p>オペレータはIObservable&lt;T&gt;を継承しているので、メソッドチェーンすることができます</p> <p> </p> <p>ざっくりふわふわとした説明は以上</p> <p> </p> <h3>作るもの</h3> <p>オペレータの作成のためにはまず2種類のクラスと拡張メソッドを定義する必要があります</p> <p> </p> <p>具体的には</p> <p> </p> <ul> <li>OperatorObservableBase&lt;T&gt;を継承したストリームをSubscribeするクラス</li> <li>OperatorObserverBase&lt;TSource,TResult&gt;を継承したストリームを加工する処理を書くクラス</li> <li>IObservable&lt;T&gt;をソースとして受け取り、作成したOperatorObservableBase継承クラスの中にソースを流し込んでnew()して返す拡張メソッド</li> </ul> <p> </p> <p>です、最初は何言ってるかわからないと思います</p> <p> </p> <h3>適当に作っていきます</h3> <p> </p> <p>BossObservableをいうものを作ってみようと思います</p> <p>原理の説明やこれなんのGenericやねんというのはまったく説明しません </p> <p> </p> <p> </p> <p>オペレータが作成された時(newされた時)に</p> <p>「デキタヨ!」</p> <p>オペレータの中を処理が通った時に</p> <p>「トオッタヨ!」</p> <p>オペレータの中をErrorが通った時に</p> <p>「アワワワワワ」</p> <p>ストリームがCompleteした時に</p> <p>「ボクニマカセテ!」</p> <p> </p> <p>を出力したいと思います、特に意図はありません。</p> <p> </p> <p>まずはBossObservableを定義します</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/d22df2d1d6747b5a4e8125ee933760dc.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/d22df2d1d6747b5a4e8125ee933760dc">gist.github.com</a></cite></p> <p> </p> <p>これで定義できました。</p> <p>基本的にObserverOperatorBaseを継承したクラスの</p> <p>new()</p> <p>OnNext()</p> <p>OnError()</p> <p>OnComplete()</p> <p>にいろいろな処理を書くことができます</p> <p> </p> <p>ストリーム中にインプットを止めたい・・・などはかなり多い拡張かと思います</p> <p> </p> <p> </p> <p>次は拡張メソッドを定義します</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/34830bfadadf8fc6d58f6f3cd7a99724.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/34830bfadadf8fc6d58f6f3cd7a99724">gist.github.com</a></cite></p> <p> </p> <p> </p> <p>シンプルです、前回のオペレータをsourceとして引数で引っ張ってきて、newして返すだけです</p> <p>途中の処理は重複回避やnullチェックですが、重複してもよければ省きましょう</p> <p> </p> <p>以上でBossの定義ができました</p> <p> </p> <p> </p> <p>これで全てのストリームに対して.Boss()を挟むことができます</p> <p>やったぜ</p> <p> </p> <p> </p> <h3>最後に</h3> <p>UniRxに既に定義されているオペレータだけでも処理はできますが、やはり1つラップされた処理があると使う方は非常に楽です</p> <p> </p> <p>書いていれば理解できてくると思うので、ぜひいろいろ試してみてください</p> yutakaseda3216 【Unity】Zenjectをマルチシーンで使うときの3つの方法 hatenablog://entry/8599973812272902737 2017-06-22T18:21:50+09:00 2017-06-23T10:12:12+09:00 Zenject関係の過去記事 yutakaseda3216.hatenablog.com yutakaseda3216.hatenablog.com マルチシーンでZenjectを使う 少し慣れてきた人向けです Zenjectの中核となるDiContainerは、SceneContextというクラスに紐付いている SceneContextが破棄されることでBindされていたデータも破棄されてしまうため、シーンを跨いでSceneContextが破棄される場合、データを保持できない また、複数シーンを使用する場合、各々にSceneContextが存在する場合、何もしなければContext間でBin… <h4>Zenject関係の過去記事</h4> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【Unity】Zenjectで禅の心を手に入れる - 開発とかメモ。" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fyutakaseda3216.hatenablog.com%2Fentry%2F2017%2F04%2F17%2F124612" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2017/04/17/124612">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【Unity】ZenjectのAsSingle(),AsCached(),AsTransient()の違い - 開発とかメモ。" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fyutakaseda3216.hatenablog.com%2Fentry%2F2017%2F04%2F21%2F153555" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2017/04/21/153555">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p> </p> <h4>マルチシーンでZenjectを使う</h4> <p> </p> <p>少し慣れてきた人向けです</p> <p> </p> <p>Zenjectの中核となる<a class="keyword" href="http://d.hatena.ne.jp/keyword/DiContainer">DiContainer</a>は、SceneContextというクラスに紐付いている</p> <p> </p> <p>SceneContextが破棄されることでBindされていたデータも破棄されてしまうため、シーンを跨いでSceneContextが破棄される場合、データを保持できない</p> <p> </p> <p>また、複数シーンを使用する場合、各々にSceneContextが存在する場合、何もしなければContext間でBindされた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>は共有されない</p> <p> </p> <p>そのため、マルチシーン用の機能を使う必要がある</p> <p> </p> <p>方法は三種類ある</p> <p> </p> <p> </p> <h4>1.ProjectContextを使用する</h4> <p><a href="https://github.com/modesttree/Zenject#global-bindings">https://github.com/modesttree/Zenject#global-bindings</a></p> <p> </p> <p>ProjectContextをSceneContextと同様に作成してprefab化する</p> <p>InstallerをprefabにアタッチしてAssets/Resources/以下に置くことで</p> <p><span style="color: #d32f2f;">いずれかのSceneContextが読み込まれた際に自動でResources.Loadで生成される</span></p> <p>ようになる</p> <p> </p> <p>ProjectContextの特徴として</p> <p> </p> <ul> <li>DontDestroy属性付きで生成される</li> <li>全てのSceneContextから参照される</li> </ul> <p> </p> <p>ため、各SceneContextから、ProjectContextでBindされた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を参照することが可能になる</p> <p> </p> <p>また、ProjectContextを操作したい場合はsingletonになっているので</p> <p> </p> <pre class="code" style="overflow-x: auto; overflow-y: hidden; margin: 0px; padding: 10px; border: 1px solid rgba(255, 255, 255, 0.098); outline: 0px; font-size: 13px; vertical-align: baseline; background: rgba(0, 0, 0, 0.2); border-radius: 3px; font-family: Monaco, Consolas, 'Courier New', Courier, monospace, sans-serif; color: #c1cdd6; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;" data-lang="" data-unlink="">ProjectContext.Instance.Container</pre> <p> </p> <p>で取得できる</p> <p> </p> <p>どのSceneContextが読み込まれた時でも生成されるので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>でも本番環境でもいてほしいBind<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>はこれで良いと思う</p> <p> </p> <p> </p> <p>ただ、デメリットとして、いついかなる時でもSceneContextが生成されるとひっついてくるので、Testなどには向かない可能性高し</p> <p> </p> <h4>2.ContractNameを使用したParenting</h4> <p><a href="https://github.com/modesttree/Zenject#scene-parenting">https://github.com/modesttree/Zenject#scene-parenting</a></p> <p> </p> <p>ProjectContextを<span style="color: #d32f2f;">使用しない方法その1</span></p> <p> </p> <p>SceneContextには、ContractNameというパラメータを設定できる</p> <p> </p> <p>これの</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170622174720p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170622/20170622174720.png" alt="f:id:yutakaseda3216:20170622174720p:plain" /></p> <p> </p> <p>ここ</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170622174734p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170622/20170622174734.png" alt="f:id:yutakaseda3216:20170622174734p:plain" /></p> <p> </p> <p>ContractNameを設定することで、SceneContextに属性を設定することができる</p> <p> </p> <p>また勘のいい人はすでにお気づきかもしれないが</p> <p> </p> <p>すぐ下に"ParentContractName"なるパラメータがある</p> <p> </p> <p>ここに指定したContractNameの属性を持つSceneContextがParentとして参照されることで親の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>がBindされているかの様に振る舞うことができるができる</p> <p> </p> <p>Parentに指定したSceneContextが読み込まれていない場合、エラーになるので読み込み順には気をつけよう</p> <p> </p> <p>また、Parentに指定されたSceneContextが先に破棄された場合も同様にエラーになる</p> <p> </p> <p>特徴をまとめる</p> <ul> <li>Parentは子のContextを参照できない</li> <li>Parentは子のContextより先に読み込まれていないといけない</li> <li>Parentが子より先に破棄されてはいけない</li> </ul> <p> </p> <p>使用するメリットとして、同じContractNameをつけることで</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>用</p> <p>本番用</p> <p>テスト用</p> <p>などのContextを用意し、状況に応じてシーンを付け替え、動作を変えることができる点があげられる</p> <p> </p> <p>子からParentになっているSceneContextのContainerを指定してアクセスする場合</p> <p>子のContainerをInjectで取得して</p> <p> </p> <pre class="code" style="overflow-x: auto; overflow-y: hidden; margin: 0px; padding: 10px; border: 1px solid rgba(255, 255, 255, 0.098); outline: 0px; font-size: 13px; vertical-align: baseline; background: rgba(0, 0, 0, 0.2); border-radius: 3px; font-family: Monaco, Consolas, 'Courier New', Courier, monospace, sans-serif; color: #c1cdd6; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;" data-lang="" data-unlink="">Container.ParentContainer</pre> <p>で取得できる</p> <p> </p> <h4>3.ContractNameを使用したDecorating</h4> <p><a href="https://github.com/modesttree/Zenject#scene-decorators">https://github.com/modesttree/Zenject#scene-decorators</a></p> <p> </p> <p>ProjectContextを<span style="color: #d32f2f;">使用しない方法その2</span></p> <p> </p> <p>前述のSceneParentingよりもシンプル</p> <p> </p> <p>SceneContextを作成するのと同じ様に、DecoratorContextを作成する</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170622175838p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170622/20170622175838.png" alt="f:id:yutakaseda3216:20170622175838p:plain" /></p> <p> </p> <p>DecoratedContractNameに、SceneContextに設定したContractNameを指定する</p> <p>あとはInstallerを追加して〜で終わり</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>コマンドの追加や、元となるシーンに対して何かを付加する場合に使用すると良い</p> <p>元のシーンを全くいじることなく、何かの機能を付与することができる</p> <p> </p> <p> </p> <p>またSceneParentingを使用した場合と違って</p> <p> </p> <ul> <li>DecoratorContextと指定したSceneContextは<span style="color: #d32f2f;">相互に参照できる</span></li> <li>DecoratorContextのあるシーンは指定したSceneContextの<span style="color: #d32f2f;">前にロードされていないといけない</span></li> </ul> <p> </p> <p>点に注意する、特に二個目はクセが強いと思うので・・・</p> <p> </p> <p> </p> <h4>まとめ</h4> <p> </p> <p>SceneParentingだけ使えばいいんじゃないかな感があるものの、それぞれメリットがあるので一考する</p> <p> </p> <p>あと、UniRxとMVP(っぽい)設計とZenjectを組み合わせた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>を試行錯誤しながら大体まとめられた気がするので、いつか書きたいなと思う(弱気)</p> <p> </p> <p>Zenjectを使ってUnityの最前線(笑)にいる気持ちで開発しよう!</p> <p> </p> <p> </p> <h5>ついでに</h5> <p><span style="font-size: 80%;">実はもう一個シーン間の受け渡し方法があるんですが、ZenjectSceneHandlerで調べてください</span></p> <p><span style="font-size: 80%;">めんどくさすぎるので紹介しませんでした</span></p> yutakaseda3216 【Unity】アセットストアで地雷を踏まないための5つのTips hatenablog://entry/8599973812270152077 2017-06-15T12:51:26+09:00 2017-07-30T18:26:34+09:00 2017/7/10追記 アセットストアがアップデートされ、見た目が大幅に変わりました 一部のTipsがあまり意味をなしていない場合があります あんまり変わってなかった アセットストア モデル、サウンド、エディタ拡張、完成プロジェクトまで様々なアセットを販売、購入できるプラットフォーム 高品質なアセット(普通に発注すればうん百万は下らなさそうなもの)も100$前後で買えたりします Unityを使う一つの理由と言っても過言ではないんですが・・・ 地雷が多いんじゃ 審査さえ通れば誰でも販売できる・・・そのため 品質がまちまち まともに動かすためには特定の手順が必要 他のアセットと競合 importす… <p> </p> <h3>2017/7/10追記</h3> <p><span style="text-decoration: line-through;">アセットストアがアップデートされ、見た目が大幅に変わりました</span></p> <p><span style="text-decoration: line-through;">一部のTipsがあまり意味をなしていない場合があります</span></p> <p>あんまり変わってなかった</p> <p> </p> <h3>アセットストア</h3> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615120957p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615120957.png" alt="f:id:yutakaseda3216:20170615120957p:plain" /></p> <p>モデル、サウンド、エディタ拡張、完成プロジェクトまで様々なアセットを販売、購入できるプラットフォーム</p> <p>高品質なアセット(普通に発注すればうん百万は下らなさそうなもの)も100$前後で買えたりします</p> <p>Unityを使う一つの理由と言っても過言ではないんですが・・・</p> <p> </p> <h4>地雷が多いんじゃ</h4> <p>審査さえ通れば誰でも販売できる・・・そのため</p> <ul> <li>品質がまちまち</li> <li>まともに動かすためには特定の手順が必要</li> <li>他のアセットと競合</li> <li>importするとエラー</li> <li>etc</li> </ul> <p>などなどの問題が多発します</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/C%23">C#</a>やUnity<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>などに深い知識がない人は、エラーを解決できずに泣く泣くアセットを使わない選択をすることもあると思います</p> <p> </p> <p>なので、アセットストアで購入する際に地雷(が比較的多い)を選別するTipsを書こうと思います</p> <p> </p> <p>ちなみに書いてる本人はアセットを15万円分くらい買ってます^p^</p> <p> </p> <h4>Tips.1 - 作成バージョンを見る</h4> <p> </p> <p>例でPlaymakerを見てみます</p> <p>このトップ画面の下部にある</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615121120p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615121120.png" alt="f:id:yutakaseda3216:20170615121120p:plain" /></p> <p>ここに注目します</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615121158p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615121158.png" alt="f:id:yutakaseda3216:20170615121158p:plain" /></p> <p> </p> <p>「パッケージはUnity....で作られました」という表示があります</p> <p> </p> <p>ここの部分の対応バージョンが自分の使用しているバージョンをサポートしているかを見てみましょう</p> <p>この画像では最高で5.4.0となっています</p> <p> </p> <p> </p> <p>つまるところ、現在最新版のUnity5.6.1で正常動作する保障はされておりません</p> <p>表記がそうなっているだけで、5.6での動作を確認している場合もあるようです</p> <p> </p> <p> </p> <p>さすがに、Unity5で使用したいのにUnity4で作成されたアセットなどの場合は気をつけましょう</p> <p> </p> <h4>Tips.2 - アップデートの頻度を見る</h4> <p> </p> <p>アセットは、アセットの開発元がユーザーからのバグ報告対応や、Unityのアップデートに合わせてバージョンアップする場合があります</p> <p> </p> <p>このアップデートの頻度が高いほど、信頼度が高いです</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615121158p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615121158.png" alt="f:id:yutakaseda3216:20170615121158p:plain" /></p> <p> </p> <p>バージョンの数字をクリックするとリリースノートを見ることができます</p> <p> </p> <p>また、サポートウェブサイトとパブリッシャーサイトもチェックしてみましょう</p> <p>詳細なアップデート履歴が観れる場合があります</p> <p> </p> <p>ここが404NotFoundになっている場合、アップデートはほぼ絶望的と思ってもらって構わないと思います</p> <p> </p> <h4>Tips.3 - <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リ構成を見る</h4> <p> </p> <p>アセットに含まれるファイルやフォルダ構成をパッケージ内容という部分で見ることができます</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615122526p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615122526.png" alt="f:id:yutakaseda3216:20170615122526p:plain" /></p> <p> </p> <p>ここの判断基準は幾つかあります</p> <p> </p> <ul> <li> <h5>StandardAssetsが含まれているかどうか</h5> </li> </ul> <p> </p> <p> </p> <p>まず、StandardAssetsが含まれている場合が一番危険です</p> <p>Unity4やUnity5のStandardAssetsが含まれている場合がある上に、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リが違う場合重複してインポートされます</p> <p> </p> <p>そのため、DemoSceneなどで使用しているという理由でStandardAssetsが含まれている場合は注意しましょう</p> <p> </p> <p>もちろんimport時に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%A7%A5%C3%A5%AF%A5%DC%A5%C3%A5%AF%A5%B9">チェックボックス</a>を外し、importしなければ問題はないです</p> <p> </p> <p> </p> <ul> <li> <h5>パッケージのルート<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リが一つになっているかどうか</h5> </li> </ul> <p> </p> <p> </p> <p>ルート<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リが一つになっていない場合(最近はアセットストアのルールで絶対になっているらしい?)</p> <p>自分で作った<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リと重複する可能性があるため、非常に困ります</p> <p> </p> <p> </p> <ul> <li> <h5>ネイティブ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使用していないのにPlugins<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リが入っているかどうか</h5> </li> </ul> <p> </p> <p> </p> <p>これもおかしな話です、かなり少数ですがPlugins<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リに入っているアセットが幾つかあります</p> <p> </p> <p><span style="color: #d32f2f;">追記</span></p> <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Pluginsに入れる理由としてはAssemblyがfirstpassに移るからっていうのがありますね<br><a class="keyword" href="http://d.hatena.ne.jp/keyword/C%23">C#</a>で作っていてもjsからアクセスできるようになったり、ユーザーが無名空間に作ったクラス名と競合してもAssemblyが分かれるので衝突しないとか、いろいろ利点があります <a href="https://t.co/3Hv6n6plUX">https://t.co/3Hv6n6plUX</a></p>&mdash; <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B1%A5%C3%A5%C8%A5%B7%A1%BC">ケットシー</a>ウェア (@caitsithware) <a href="https://twitter.com/caitsithware/status/875202909067026432">2017年6月15日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <p>Arbor2(<a href="https://www.assetstore.unity3d.com/jp/#!/content/47081">https://www.assetstore.unity3d.com/jp/#!/content/47081</a>)の作者様よりご指摘がありましたので引用させていただきます</p> <p>Pluginsに入っていることはアセット提供側からするとメリットがあるため、逆によく考えられていることの方が多いかもしれませんね</p> <p> </p> <p>なので、それ以外の場合(モデルデータや明らかにおかしいもの)は少し考えた方が良さそうです</p> <p> </p> <p> </p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>の名前</li> </ul> <p> </p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>の名前がCameraControllerやGameControllerなど、重複する可能性の高い名前の場合注意が必要です</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を消すことでアセット自体が動作しなくなることもあり、コードを修正する必要が出てきます</p> <p> </p> <p> </p> <ul> <li> <h5>ファイルの名前に全角文字やスペース、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%C3%BC%EC%CA%B8%BB%FA">特殊文字</a>が含まれているかどうか</h5> </li> </ul> <p> </p> <p> </p> <p>これは基本的には問題にならないのですが、Gitなどを使用したバージョン管理をする場合非常に問題になります</p> <p>一度<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%CB%C2%CE%BB%FA">繁体字</a>が紛れていたことがあり修正に時間を取られました</p> <p>気をつけましょう</p> <p> </p> <p> </p> <h4>Tips.4 - レビューではなくサポートフォーラムを見る</h4> <p> </p> <p> </p> <p>ページ下部にあるレビュー欄</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170615123840p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170615/20170615123840.png" alt="f:id:yutakaseda3216:20170615123840p:plain" /></p> <p> </p> <p>仮でピックアップしてみましたが、全く当てになりません</p> <p>現在のバージョンではないレビューの場合があるためです</p> <p> </p> <p>また、1年前や2年前の投稿が出てくることはザラです、信用しないようにしましょう</p> <p> </p> <p>現在進行形でアセットの評価をみたい場合はこちらを利用すると良いです</p> <p> </p> <p><a href="https://forum.unity3d.com/forums/assets-and-asset-store.32/">https://forum.unity3d.com/forums/assets-and-asset-store.32/</a></p> <p> </p> <p>Unityの公式フォーラム内にある、AssetStore関連のスレッド群です</p> <p> </p> <p>利用したいアセット名で検索することで、ユーザーの感想、問題点の共有や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D9%A5%ED%A5%C3%A5%D1">デベロッパ</a>ーとのやりとりを見れる場合があります</p> <p> </p> <p> </p> <p>私も<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D9%A5%ED%A5%C3%A5%D1">デベロッパ</a>ーに(本当にたまに)意見を言っています、だいたい拾ってくれますし丁寧に答えてくれることが多いです</p> <p>英語ですが</p> <p> </p> <p> </p> <h4>Tips.5 - 使った人のレビューブログを見たり、可能なら直接聞く</h4> <p> </p> <p> </p> <p>当たり前の話ですが、一番確実です。</p> <p>特にUnityはコミュニティが強いので、日本人もたくさんいます、聞きましょう</p> <p> </p> <p> </p> <p> </p> <h4>最後に</h4> <p>「超個人的」な印象ですがSimpleとかEasyとかついてるアセットをあまり信用してないです</p> <p>判断基準の一つになれば幸いです、良いUnityライフを</p> <p> </p> <p> </p> <p><span style="color: #d32f2f;">アセットもバリバリ使ってる現在開発中のゲームの公式サイトはこれ(宣伝)</span></p> <p><a href="https://www.studiophantomisland.com/">https://www.studiophantomisland.com/</a></p> <p> </p> <p> </p> <p>よろしくお願いしますーす</p> yutakaseda3216 BitBucketのプラン改定でLFS容量が10GBから1GBになった話 hatenablog://entry/8599973812269879649 2017-06-14T14:28:04+09:00 2017-06-14T14:28:04+09:00 BitBucketのプラン改定 Pricing Updateというまあありていにいえば価格改定が行われ その結果無料プラン、有料プランにLFSの容量が組み込まれた 改定前 リポジトリ容量2GB limit LFS容量10GB limit 改定後 リポジトリ容量2GB limit LFS容量1GB limit (!!!!?????) LFSの容量は有料プランの段階に応じて5GB -> 10GBと増え それ以上はストレージ容量を月額で買う感じのようだ 値段は10$ / monthで100GB使える 結局 むしろよく10GBも使わせてくれてたよなと思いつつも、急に変えられて困った 支払い関係でpay… <h3>BitBucketのプラン改定</h3> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170614141506p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170614/20170614141506.png" alt="f:id:yutakaseda3216:20170614141506p:plain" /></p> <p> </p> <p>Pricing Updateというまあありていにいえば価格改定が行われ</p> <p>その結果無料プラン、有料プランに<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>の容量が組み込まれた</p> <p> </p> <h4>改定前</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>容量2GB limit</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>容量10GB limit</p> <p> </p> <h4>改定後</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>容量2GB limit</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>容量1GB limit  </p> <p>(!!!!?????)</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>の容量は有料プランの段階に応じて5GB -&gt; 10GBと増え</p> <p>それ以上はストレージ容量を月額で買う感じのようだ</p> <p> </p> <p>値段は10$ / monthで100GB使える</p> <p> </p> <h3>結局</h3> <p>むしろよく10GBも使わせてくれてたよなと思いつつも、急に変えられて困った</p> <p>支払い関係で<a class="keyword" href="http://d.hatena.ne.jp/keyword/paypal">paypal</a>が使えず(外部連携すれば使える)</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/JCB">JCB</a>のカードしか持っていない弱小の僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a>の有料プランへ移行した</p> <p> </p> <p>private<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>を作るために<a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a>の有料アカウントを取得</p> <p>毎月5$払って<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>容量を50GB買っている</p> <p> </p> <p>だいたい月に12$弱持ってかれてる計算だ</p> <p> </p> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/Github">Github</a>に移行してから</h4> <p>とりあえず<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>で使用している<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>容量が9GBほどあったので、cloneに多大な時間がかかる</p> <p>また、使用できる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>の通信帯域制限50GBがあるのでcloneコケすると軽く数GBの帯域を持って行かれた</p> <p> </p> <p>通信帯域制限はBitBucketにはなかったと思うので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Github">Github</a>有料にする前によく考えればよかったなーと思う</p> <p> </p> <p>Nowでこんな感じ</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170614142647p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170614/20170614142647.png" alt="f:id:yutakaseda3216:20170614142647p:plain" /></p> <p> </p> <p> </p> <p>兎にも角にも、サービスを使っているとこういうコストが生まれるので</p> <p>やっぱり自前でサーバー立ててgitlabとか使った方が最終的には安く済みそうだなと思った。</p> <p> </p> <p>終わり</p> yutakaseda3216 【Unity】ZenjectのAsSingle(),AsCached(),AsTransient()の違い hatenablog://entry/10328749687238592621 2017-04-21T15:35:55+09:00 2017-04-21T15:51:41+09:00 Zenject使うじゃんAsSingleでBindするじゃんUnBindするじゃんもう一回BindするじゃんInjectされない!!!!!!AsTransient使えば解決なんだけど、GC走って回収されてるのにキャッシュ残ってるってどういうことなんなんなん— ペンギン (@YutaDevelop) 2017年4月21日 調べてみた。 超適当にテストコード書いて挙動を確かめた メソッドの名前が意味不明なのは許してほしい // gist.github.com 挙動を理解しないとヤバい事故生みそうだなこれという結果になった 結果的にはAsSingle()でInjectされてる参照がUnbindで破棄… <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Zenject使うじゃん<br>AsSingleでBindするじゃん<br>UnBindするじゃん<br>もう一回Bindするじゃん<br>Injectされない!!!!!!<br><br>AsTransient使えば解決なんだけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>走って回収されてるのにキャッシュ残ってるってどういうことなんなんなん</p>&mdash; ペンギン (@YutaDevelop) <a href="https://twitter.com/YutaDevelop/status/855263000080523264">2017年4月21日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <p> </p> <h3>調べてみた。</h3> <p> </p> <p>超適当にテストコード書いて挙動を確かめた</p> <p>メソッドの名前が意味不明なのは許してほしい</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/417bee0cd5ae7fcfa240993aab37b2b5.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/417bee0cd5ae7fcfa240993aab37b2b5">gist.github.com</a></cite></p> <p> </p> <p>挙動を理解しないとヤバい事故生みそうだなこれという結果になった</p> <p>結果的にはAsSingle()でInjectされてる参照がUnbindで破棄されてなくて、Inject済みの参照をもう一回Bindし直してた</p> <p>あと<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>で回収されてなかった</p> <p> </p> <h3>そもそも</h3> <p>As〜ってなんぞやというと</p> <p>Bindするクラスや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>のBind方法の定義である</p> <p> </p> <p><a href="https://github.com/modesttree/Zenject#binding">https://github.com/modesttree/Zenject#binding</a></p> <p> </p> <p>AsSingle(),AsCached()はキャッシュするのね〜</p> <p>AsTransientはキャッシュ作らないのね〜くらいの認識だと</p> <p><span style="font-size: 150%; color: #d32f2f;">しぬ(しんだ)</span></p> <p> </p> <h4>AsTransient()</h4> <p>クラスをBindする際に複数<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の生成を許容する</p> <p>クラスがContainerにBindされている際、参照情報が一つであればResolveで解決出来る</p> <p> </p> <p>しかし、Resolveは単一の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に対してのみ参照を解決するため</p> <p><span style="color: #d32f2f;">AsTransientでBindを複数回行っていた場合、multiple instanceエラーを吐く</span></p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/622db72c60bc82f626f03aaec41583ba.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/622db72c60bc82f626f03aaec41583ba">gist.github.com</a></cite></p> <p> </p> <p>AsTransientでのBindには必ず.WithId()を使用してIdentiferを定義するか</p> <p>ResolveAllを使用した参照解決を図るようにした方が良い</p> <p> </p> <p>また、As〜などの定義をしなかった場合はデフォルトでAsTransientになる</p> <p>Factoryなどを使用した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>生成もAsTransientになるため、Instantiateで複数生成したクラスに対してResolveするとエラー吐く、気をつけよう</p> <p>(まあInstantiateした時点でResolveすることなんてほとんどないんだけど)</p> <p> </p> <h4>AsCached()</h4> <p>Bindされているクラスがすでに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>化されている場合、同じ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を使い回すようにする</p> <p>また、UnbindするとCacheされていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>は全て参照を破棄される</p> <p> </p> <p><span style="color: #d32f2f;">同じ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>は使いまわしたいが、Unbindで破棄したい時はこれを使用する</span></p> <p><span style="color: #d32f2f;">クセがなく、取り回しがしやすいので動的Bindをする際は非常におすすめしたい</span></p> <p> </p> <h4>AsSingle()</h4> <p>クラスをBindする際にSingletonとして定義する</p> <p>クラスがContainerにBindされている際は</p> <p>「そのContainer内で唯一存在するクラス」となることが保障される</p> <p> </p> <p>Bindされている際は、Cachedと同じ挙動をする</p> <p> </p> <p>しかし、Unbindを呼んだ際に</p> <p><span style="color: #d32f2f;">Bindした自身の参照を他のクラスにInjectしなくなる</span><span style="color: #d32f2f;">が、生成した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>自体は破棄されずキャッシュされたまま</span></p> <p>のため、Unbindを呼び、その後もう一度同じクラスをBindしても</p> <p><span style="color: #d32f2f;">new()などが走らず</span>、キャッシュされていた参照をもう一度Bindして使い回す</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/1acd9571a6c7db4f8a64a72d00b3195e.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/1acd9571a6c7db4f8a64a72d00b3195e">gist.github.com</a></cite></p> <p><span style="font-size: 80%;">(HashCodeでやっているが、他にもResolveで返ってきた値の中身を書き換えたところどちらも書き換わった)</span></p> <p> </p> <p>AsSingle()は必ず一つ、かつ一度しか生成されないオブジェクトに対してのみ使用しよう</p> <p> </p> <p> </p> <h4>まとめ</h4> <p>readmeには、「AsSingle()をほとんどの場面で使いたいと思うでしょうが〜」とか書いてあるけど</p> <p>基本AsCached()でいいわ。</p> <p> </p> <p>AsSingle()で動的Bindすると初期化走らせられなくてビビった結果、動作を知れたのでまあよかったと思う。</p> <p> </p> <p>あと、ZenjectのUnitTestマジで神以外の何物でもないので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%F3">バン</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%F3">バン</a>使っていきたい</p> yutakaseda3216 【Unity】Zenjectで禅の心を手に入れる hatenablog://entry/10328749687237540072 2017-04-17T12:46:12+09:00 2017-04-17T13:14:21+09:00 Zenjectについて github.com 導入を躊躇っていたものの、あるところから脅しがかかったので本格的に使い始めた 基本的な使い方などはこちらをご参考いただければわかるのではないかと思います Unity3DのDIフレームワーク、Zenjectの紹介 | Aiming 開発者ブログ 今回はちょっと具体的な使い方を模索してみました。 何ができるのか リポジトリのreadmeを読めばわかる DI(Dependancy Injection)を行うためのライブラリで、すっごい簡単に言うと newの引数とか、シングルトンで引っ張ってきてたオブジェクトを、登録しておいたオブジェクトの中から勝手に引っ… <p> </p> <h3>Zenjectについて</h3> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="modesttree/Zenject" src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fmodesttree%2FZenject" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://github.com/modesttree/Zenject">github.com</a></cite></p> <p> </p> <p>導入を躊躇っていたものの、あるところから脅しがかかったので本格的に使い始めた</p> <p> </p> <p>基本的な使い方などはこちらをご参考いただければわかるのではないかと思います</p> <p><a href="https://developer.aiming-inc.com/unity/zenject/">Unity3DのDIフレームワーク、Zenjectの紹介 | Aiming 開発者ブログ</a></p> <p> </p> <p>今回はちょっと具体的な使い方を模索してみました。</p> <p> </p> <h3>何ができるのか</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>のreadmeを読めばわかる</p> <p>DI(Dependancy Injection)を行うためのライブラリで、すっごい簡単に言うと</p> <p> </p> <p><strong>newの引数とか、シングルトンで引っ張ってきてたオブジェクトを、登録しておいたオブジェクトの中から勝手に引っ張ってきて自動で参照を入れてくれるやつ</strong></p> <p> </p> <p>って認識でいいと思う、もちろんこれは機能のごく一部に過ぎない</p> <p>他にもいろいろできる、公式読んで </p> <p> </p> <h3>中身の話</h3> <p>Zenjectの基本は</p> <p> </p> <ol> <li>Containerにオブジェクトを登録</li> <li>Containerに登録したオブジェクトを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>化(この時に引数などの参照が自動で持ってこられる)</li> <li>オブジェクトが作られたらごにょごにょする</li> </ol> <p> </p> <p>になる</p> <p>Containerは、登録されたオブジェクトが入ってるDictionaryみたいなもので</p> <p>ここの中にオブジェクトが登録されていないと、参照を解決できない</p> <p>また、自動で参照してくれるようにするためには、参照先のオブジェクトも登録してあげないといけない</p> <p> </p> <p>つまり、こう</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/77545c44bf6d16c8f060765a6bea2beb.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/77545c44bf6d16c8f060765a6bea2beb">gist.github.com</a></cite></p> <p> </p> <p>これは全てにおいて適用されるので、まずBindを忘れないようにしよう。</p> <p> </p> <h3>使い方</h3> <p>まだ全てを把握できているわけではないので、状況別で</p> <p> </p> <p> </p> <h4>SingletonにしていたManagerを、Singletonにしない</h4> <p><span style="font-size: 80%;">(MonoBehaviour継承クラスに、参照を渡す方法)</span></p> <p> </p> <p>Zenjectには、ZenjectBindingという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>が存在する</p> <p>こいつは、登録した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>を勝手にContainerに登録してくれるすごいやつ</p> <p> </p> <p>実際に使ってみるとこうなる</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170417121301p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170417/20170417121301.png" alt="f:id:yutakaseda3216:20170417121301p:plain" /></p> <p> </p> <p>Managerの中身は、普通のMonoBehaviour継承クラスになっている</p> <p>使用する場合は、こう書く</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/2fa7656688e1260ede39626ce53f47f3.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/2fa7656688e1260ede39626ce53f47f3">gist.github.com</a></cite></p> <p> </p> <p>MonoBehaviour継承クラスの場合は、Inject<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>を使用することで自動で参照が設定される</p> <p>非継承の場合は、newで渡してあげる</p> <p> </p> <p>これで、Managerは自動で使いたいところで使えるようになるので、ただのstatic参照のためだけにSingletonである必要がなくなる</p> <p><span style="font-size: 80%;">もちろん、同一<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>が一つしかないことを保証するために使うのはあり</span></p> <p><span style="font-size: 80%;">同一クラスは一つのみ生成し、あとはキャッシュを使う.AsSingle()というBind方法が存在する</span></p> <p>  </p> <p>同じことをしてる人がいたので、こちらも</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="グローバルゲームジャムでクラス設計をやった話2017 - Qiita" src="//hatenablog-parts.com/embed?url=http%3A%2F%2Fqiita.com%2FtoRisouP%2Fitems%2F5b7814fda00cab120e39%23%25E3%2581%258A%25E3%2581%25BE%25E3%2581%25912-zenject%25E4%25BD%25BF%25E3%2581%25A3%25E3%2581%25A6%25E3%2581%25BF%25E3%2581%259F" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://qiita.com/toRisouP/items/5b7814fda00cab120e39#%E3%81%8A%E3%81%BE%E3%81%912-zenject%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F">qiita.com</a></cite></p> <p><span style="font-size: 80%; color: #cccccc;">余談ですが、torisoupさんはいつも勉強になる記事をあげてくださっているので定期購読をお勧めします</span></p> <p> </p> <p>また、Manager以外にもZenjectBindingに登録さえすればなんでも使えます</p> <p>Playerとかカメラとかを登録すると捗るかもね</p> <p> </p> <h4> Pureクラスを好きなタイミングでBindしながら生成する</h4> <p> </p> <p>MonoBehaviourの参照を渡したりするPureクラスとか・・・</p> <p>クラスがごちゃごちゃしがちな原因の一つだが、Zenjectを使用することで解決出来る</p> <p> </p> <p> </p> <p>まずMonoBehaviour継承クラスで渡したいクラスをBindする</p> <ul> <li>シーンに最初から直置きしてあればZenjectBindingを使用する</li> <li>動的に生成される場合は、Container.Bindを使用してContainerに登録する</li> </ul> <p> </p> <p>動的生成する際に勘違いされがちだが</p> <p><span style="color: #d32f2f;">別にInstallerを使って記述しなくてもいい</span></p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/DIContainer">DIContainer</a>へのBindさえできればよく、さらに</p> <p><span style="color: #d32f2f;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/DIContainer">DIContainer</a>はBindされているので好きなクラスにInjectで引っ張ってこれる</span></p> <p>好きなタイミングでBindすればいいと思う</p> <p> </p> <p> 試しに、ボタンを押したら<a class="keyword" href="http://d.hatena.ne.jp/keyword/Hoge">Hoge</a>をBindして生成するにはこうする</p> <p> </p> <p> <script src="https://gist.github.com/yuta-kaseda/d62a3c1326c70be37f776c116c907dbc.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/yuta-kaseda/d62a3c1326c70be37f776c116c907dbc">gist.github.com</a></cite></p> <p> </p> <p>GameManagerはBindInstallerか何かでBindしてあげる必要があるが</p> <p>Bindさえすれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/DIContainer">DIContainer</a>を引っ張ってこれるのでこういう書き方ができる</p> <p> </p> <p>Container.Resolve&lt;<a class="keyword" href="http://d.hatena.ne.jp/keyword/Hoge">Hoge</a>&gt;()はBindされているオブジェクトを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>化してreturnするメソッド</p> <p>他にも.TryResolve&lt;T&gt;()などのメソッドが用意されているので、動的バインドする基底クラスかヘルパーを作ることをお勧めする</p> <p> </p> <p>Resolveについては公式を</p> <p><a href="https://github.com/modesttree/Zenject#dicontainer-methods-resolve">https://github.com/modesttree/Zenject#dicontainer-methods-resolve</a></p> <p> </p> <p>ちなみに、BindされたPureクラスは明示的にUnBindしない限り<span style="color: #d32f2f;">参照を握られ続けるため破棄されない</span></p> <p>Disposeメソッドなどを使い、破棄するタイミングでContainer.UnBind&lt;<a class="keyword" href="http://d.hatena.ne.jp/keyword/Hoge">Hoge</a>&gt;()を呼んであげよう</p> <p> </p> <p><span style="font-size: 80%;">(これって非推奨だったりするのかな、知っている人がいたら教えてください)</span></p> <h4>その他</h4> <p>.FromNew</p> <p>.FromMethodsとかは紹介したかったのですが、長くなりそうなのでまとめたときにでも</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/DIContainer">DIContainer</a>.Inject</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/DiContainer">DiContainer</a>.Instantiate</p> <p>は今試してます。追記予定。</p> <p> </p> <p>処理速度とかの測定はしてないんだけど、Bindは<span style="color: #d32f2f;">結構重いらしい</span></p> <p>まあそうだろうねって感じだけど、これも測らないといけないね</p> <p> </p> <p>終わり</p> <p>禅の心強いわー</p> yutakaseda3216 【Unity】StateMachineBehaviourについてと注意まとめ hatenablog://entry/10328749687235088032 2017-04-06T10:53:15+09:00 2017-04-06T12:04:31+09:00 StateMachineBehaviourとは 過去記事 yutakaseda3216.hatenablog.com yutakaseda3216.hatenablog.com AnimatorのStateにAddComponentできるスクリプト(MonoBehaviourみたいな感じ) クラスに継承させることで使用できる 役に立たない公式リファレンスはこれhttps://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.html 動作 基本的には用意されたコールバックをoverrideすることで使用する OnStat… <h1 id="1-0-0">StateMachineBehaviourとは</h1> <p> </p> <p>過去記事</p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="UnityのStateMachineBehaviourについてのメモ - 開発とかメモ。" src="http://yutakaseda3216.hatenablog.com/embed/2016/08/28/010328" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2016/08/28/010328">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【Unity】OnStateMoveをoverrideするとRootMotionが適用されずに詰む - 開発とかメモ。" src="http://yutakaseda3216.hatenablog.com/embed/2017/04/02/232055" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2017/04/02/232055">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <p> </p> <p>AnimatorのStateにAddComponentできる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a><br />(MonoBehaviourみたいな感じ)</p> <p>クラスに継承させることで使用できる</p> <p>役に立たない公式リファレンスはこれ<br /><a href="https://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.html" target="_blank">https://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.html</a></p> <h1 id="2-0-0">動作</h1> <p>基本的には用意されたコールバックをoverrideすることで使用する</p> <p> </p> <ul> <li>OnStateEnter</li> <li>ステートマシンがこのステートを評価している場合、最初の Update のフレームで呼び出されます。</li> </ul> <p>MonoBehaviourで言うところのStart()</p> <p> </p> <ul> <li>OnStateUpdate</li> <li>最初と最後のフレームを除いて Update フレームごとに呼び出されます。 </li> </ul> <p>MonoBehaviourで言うところのUpdate()</p> <p> </p> <ul> <li>OnStateExit</li> <li>ステートマシンがこのステートを評価している場合、最後の Update のフレームで呼び出されます。 </li> </ul> <p>MonoBehaviourで言うところのOnDestroy()</p> <p><br />Update()が完全に流れなくなるフレームで呼ばれる</p> <p> </p> <p> </p> <p>----------この辺からよく知らずに使うと闇---------------------------------</p> <p> </p> <p> </p> <ul> <li>OnStateIK</li> </ul> <ul> <li>MonoBehaviour.OnAnimatorIK の直後に呼び出されます。</li> </ul> <p>IKを使用した処理を行う</p> <p><br />overrideすると、IKの処理を自前で実装することになり(Animator.SetIK〜を使う)</p> <p><span style="color: #d32f2f;"> </span></p> <p><span style="color: #d32f2f;">Stateに対してIKが自動で適用されなくなる</span></p> <p>base.OnStateIKを呼んでもダメ</p> <p> </p> <p>基本overrideする必要なし</p> <p> </p> <ul> <li>OnStateMove</li> <li>MonoBehaviour.OnAnimatorMove の直後に呼び出されます。 </li> </ul> <p>Animationに設定されたRootAnimationの処理を行う</p> <p> </p> <p>Animation内のPosition、Rotation、Scaleに関わる処理が行われるため</p> <p> </p> <p><span style="color: #d32f2f;">overrideすると、Stateに対してRootAnimationが適用されなくなる</span></p> <p>base.OnStateMoveを呼んでもダメ </p> <p> </p> <p>基本overrideする必要なし</p> <p> </p> <p> </p> <h3 id="2-0-1">AnimationCrossFade時のStateの取り扱いについて</h3> <p>CrossFadeのリファレンス</p> <p><a href="https://docs.unity3d.com/jp/540/ScriptReference/Experimental.Director.IAnimatorControllerPlayable.CrossFade.html" target="_blank">https://docs.unity3d.com/jp/540/ScriptReference/Experimental.Director.IAnimatorControllerPlayable.CrossFade.html</a></p> <p><br />AnimationがCrossFadeしている時(durationが0以上の時)</p> <p> </p> <p><span style="color: #d32f2f;">CrossFadeが終了するまで、CurrentStateはCrossFade元のまま</span><br /><span style="color: #d32f2f;">さらに、normalizedTimeもそのまま加算され続ける</span></p> <p> </p> <p>normalizedTimeを使用した処理をする時は、CrossFadeを使用しないようにするか<br />自前でnormalizedTimeを使用しよう</p> <p> </p> <p> </p> <h3 id="2-0-2">最後に</h3> <p> </p> <p>用法用量を守って使う<br />基底クラスを作ろうとしてOnStateMoveとOnStateIKをoverrideすると痛い目にあう(あった)</p> yutakaseda3216 【Unity】OnStateMoveをoverrideするとRootMotionが適用されずに詰む hatenablog://entry/10328749687233794030 2017-04-02T23:20:55+09:00 2017-04-06T10:54:27+09:00 StateMachineBehaviourについてのまとめを読んでください yutakaseda3216.hatenablog.com 概要 Unity.ver 5.4.4 UnityにはStateMachineBehaviourというものがある。 Unity - スクリプトリファレンス: StateMachineBehaviour AnimatorのStateに紐づけられるスクリプトで、そこそこ便利 その中にOnStateMoveというoverrideできるメソッドがある 日本語のリファレンスはこんな感じ Unity - スクリプトリファレンス: StateMachineBehaviour.… <p>StateMachineBehaviourについてのまとめを読んでください</p> <p> </p> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【Unity】StateMachineBehaviourについてと注意まとめ - 開発とかメモ。" src="http://yutakaseda3216.hatenablog.com/embed/2017/04/06/105315" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2017/04/06/105315">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <h3>概要</h3> <p>Unity.ver 5.4.4</p> <p> </p> <p>UnityにはStateMachineBehaviourというものがある。</p> <p><a href="https://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.html">Unity - スクリプトリファレンス: StateMachineBehaviour</a></p> <p> </p> <p>AnimatorのStateに紐づけられる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>で、そこそこ便利</p> <p>その中にOnStateMoveというoverrideできるメソッドがある</p> <p> </p> <p>日本語のリファレンスはこんな感じ</p> <p><a href="https://docs.unity3d.com/jp/540/ScriptReference/StateMachineBehaviour.OnStateMove.html">Unity - スクリプトリファレンス: StateMachineBehaviour.OnStateMove(Animator animator, AnimatorStateInfo animatorStateInfo, int layerIndex)</a></p> <p>何も書いてないに等しい</p> <p> </p> <p>それで今回は表題の通り地雷を踏んだ</p> <p> </p> <h3>RootMotion</h3> <p>RootMotionはAnimationに適用されているポジションや回転をオブジェクトに作用させてくれる機能で、それがなぜか効かなくなって半ギレしていた</p> <p>(Apply Root Motionはチェックを入れていて、そのほかもろもろもすべてokだった)</p> <p> </p> <p>StateMachineBehaviour用の基底クラスを作成して、処理を共通化した時に効かなくなったので何かあるなと思い調査</p> <p> </p> <p>結果、StateMachineBehaviourのOnSTateMoveがRootMotionのPosition更新制御を行っていて、それを直接overrideして書き換えている様子</p> <p>なので、overrideしているとそのStateにセットされているアニメーションは適用されなくなるらしい</p> <p> </p> <p>base.OnStateMove()を呼んでみたものの、適用されなかったので</p> <p> </p> <p><span style="color: #d32f2f; font-size: 150%;">OnStateMove()は自前で移動処理を書かないなら</span></p> <p><span style="color: #d32f2f; font-size: 150%;">絶対にoverrideしてはいけない</span></p> <p> </p> <p>でFA、OnStateUpdateで間に合わせよう</p> <p> </p> <p> </p> <p>この辺の仕様はマジでリファレンスに書いとけよUnity</p> <p> </p> yutakaseda3216 UnityのコーディングにVisual Studio for Macを導入して一週間が過ぎた hatenablog://entry/10328749687221962326 2017-02-28T11:55:18+09:00 2017-02-28T11:58:26+09:00 誰か俺にVSforMacを入れる勇気を— ザツヨウペンギン (@YutaDevelop) 2017年2月23日 入れました、導入した後にやった設定と感想をつらつらと書きます とりあえずPreview版とはいえ、まあなかなかでした 導入・インストール New Release Preview: Visual Studio for Mac | Visual Studio ここからインストールしてください 導入・Unity側の設定 Preferences を開いて External Tools からExternal Script Editor でインストールした Visual Studio for M… <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">誰か俺にVSforMacを入れる勇気を</p>&mdash; ザツヨウペンギン (@YutaDevelop) <a href="https://twitter.com/YutaDevelop/status/834581622338904064">2017年2月23日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <p>入れました、導入した後にやった設定と感想をつらつらと書きます</p> <p>とりあえずPreview版とはいえ、まあなかなかでした</p> <p> </p> <h4>導入・インス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%EB">トール</a></h4> <p><a href="https://www.visualstudio.com/ja/vs/visual-studio-mac/">New Release Preview: Visual Studio for Mac | Visual Studio</a></p> <p>ここからインス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%EB">トール</a>してください</p> <p> </p> <h4>導入・Unity側の設定</h4> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228112214p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228112214.png" alt="f:id:yutakaseda3216:20170228112214p:plain" /></p> <p>Preferences を開いて</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228112319p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228112319.png" alt="f:id:yutakaseda3216:20170228112319p:plain" /></p> <p>External Tools からExternal Script Editor でインス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%EB">トール</a>した <a class="keyword" href="http://d.hatena.ne.jp/keyword/Visual%20Studio">Visual Studio</a> for <a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>を指定してあげる。</p> <p> </p> <p>これで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ファイルを開くと動くぞ!</p> <p> </p> <p>とはいかない、このままだとインテリセンス(補完)が効かない</p> <p> </p> <h4>導入・VSforMac側の設定</h4> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228112608p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228112608.png" alt="f:id:yutakaseda3216:20170228112608p:plain" /></p> <p><span style="font-size: 80%;">※機密プロジェクトがあるので名前がバレないように「あ」を入力してます</span></p> <p> </p> <p>Open から、Unityのプロジェクト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リの中にある.sinファイルを選択して、ソリューションを開こう</p> <p>.sinファイルがない時は、Unityで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を選択して開けば多分自動生成されるはず</p> <p> </p> <p>これでインテリセンスが効くようになる</p> <p>ただこのままだと死ぬほど使いづらいので色々カスタムする</p> <p> </p> <h4>カスタマイズ・エディタカラー</h4> <p>まずはエディタのカラーを変える、白背景とか、謎の文字色とかゴメンだし</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228113052p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228113052.png" alt="f:id:yutakaseda3216:20170228113052p:plain" /></p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Visual%20Studio">Visual Studio</a> から ユーザー設定を開く</p> <p>余談だけど日本語のメニューなのいいよね。</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228114613p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228114613.png" alt="f:id:yutakaseda3216:20170228114613p:plain" /></p> <p> </p> <p>インターフェースを エンジニア大好き Dark にした</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228113156p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228113156.png" alt="f:id:yutakaseda3216:20170228113156p:plain" /></p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AD%A5%B9%A5%C8%A5%A8%A5%C7%A5%A3%A5%BF">テキストエディタ</a>ーからColor Themeを選択、選択すればエディタが変更されるので好きな色を選ぼう</p> <p> </p> <p><span style="color: #d32f2f;">現状Theme編集機能はないらしい</span></p> <p>自分でカスタマイズしたテーマがあるときは、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MonoDevelop">MonoDevelop</a>などからエクスポートして持ってこよう</p> <p>自分は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Oblivion">Oblivion</a>派なので、今回は割愛</p> <p> </p> <h4>カスタマイズ・ポリシー</h4> <p>ソリューションごと、あるいはグローバルでコードフォーマットなどを定義できる</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228113452p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228113452.png" alt="f:id:yutakaseda3216:20170228113452p:plain" /></p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228113520p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228113520.png" alt="f:id:yutakaseda3216:20170228113520p:plain" /></p> <p>ここから新しくポリシーを作る</p> <p>基本的にはコードの書式設定から、<a class="keyword" href="http://d.hatena.ne.jp/keyword/C%23">C#</a>の設定項目を変更していく</p> <p> </p> <p>自分の好きなようにやろう</p> <p>ソリューションごとにポリシーを適用できるので、プロジェクトを複数抱えてても安心</p> <p> </p> <h5>ポリシーにAttribute改行の設定項目がない件について</h5> <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">VSforMac<br><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>の自動改行マジで何とかしろよ…_:(´ཀ`」 ∠):<br>こいつさえなければ…</p>&mdash; ザツヨウペンギン (@YutaDevelop) <a href="https://twitter.com/YutaDevelop/status/834606049659232259">2017年2月23日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">あと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>の中身にインテリセンス効かない</p>&mdash; ザツヨウペンギン (@YutaDevelop) <a href="https://twitter.com/YutaDevelop/status/834607612435931137">2017年2月23日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <p>KUSO</p> <p>Unity使ってると頻繁に出てくるSerializeField変数を一行で宣言したい時、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>で勝手に改行されるのでその度にCmd+Zを押すことになる</p> <p>その上<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>で囲むと補完されないので一回一回手打ちになる</p> <p> </p> <h4>カスタマイズ・コードテンプレート</h4> <p>とりあえず上記の問題を解決するためによく使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>をテンプレート化した</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228114225p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228114225.png" alt="f:id:yutakaseda3216:20170228114225p:plain" /></p> <p>追加する時はユーザー設定からCode Snippetsを選択して、追加をする</p> <p>また、$class$などの記述を行うことでフリー入力を作ることもできるので活用する</p> <p> </p> <p>今回、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>でよく使うSerializeFieldを登録した</p> <p>ただ、テンプレートに</p> <p> </p> <p>[SerializeField] $class$ $field$</p> <p> </p> <p>みたいな感じで記述すると勝手に改行されたのでやらないことにした</p> <p>わけわからんので製品版で早く設定追加してほしい</p> <p><span style="font-size: 80%;">ただ海外フォーラム見てると超昔から言われてるのに開発者が<a class="keyword" href="http://d.hatena.ne.jp/keyword/Resharper">Resharper</a>を使ってるからいつまでも追加されないとかなんとか</span></p> <p> </p> <h4>カスタマイズ・パフォーマンス</h4> <p>とりあえずで上記の設定を終え、使ってみると</p> <p><span style="font-size: 150%;">インテリセンス遅すぎワロタ状態</span></p> <p>だった</p> <p> </p> <p>とにかくクッソ重い、ちなみに使用してる<a class="keyword" href="http://d.hatena.ne.jp/keyword/mac">mac</a>は2015年モデルのフルカスタマイズなのでスペックが低いわけじゃないと思う</p> <p>なので、パフォーマンス改善をする</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228114922p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228114922.png" alt="f:id:yutakaseda3216:20170228114922p:plain" /></p> <p> </p> <p>まずは何はともあれ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AD%A5%B9%A5%C8%A5%A8%A5%C7%A5%A3%A5%BF">テキストエディタ</a>からアニメーションを無効に</p> <p>強調表示とかも消す</p> <p>他にも視覚効果をOFFっていく</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170228115041p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170228/20170228115041.png" alt="f:id:yutakaseda3216:20170228115041p:plain" /></p> <p> </p> <p>効果があるかはわからないものの、コードの動的<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>が走るので解析も毎回走るんじゃないかと思い解析も切った</p> <p> </p> <p>だいぶ早くなった</p> <p> </p> <h4>カスタマイズ・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a></h4> <p>人それぞれすぎるので割愛、設定しとくと楽やで(提案)</p> <p> </p> <p> </p> <h4>最後</h4> <p>頻繁に落ちる上に操作不能になる<a class="keyword" href="http://d.hatena.ne.jp/keyword/MonoDevelop">MonoDevelop</a>よりは使いやすい</p> <p>VisualStudioCode、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Atom">Atom</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>とかのエディタより<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>派なので今後に期待したい・・・特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%C8">アトリビュート</a>とパフォーマンス</p> <p>メモリ2GB食われるのでメモリの残量には気をつけよう</p> <p> </p> <p> </p> <p>もうしばらく使ってみる</p> <p> </p> yutakaseda3216 昨今のUnity開発におけるMVP設計思想についてと、それの適用可否の話 hatenablog://entry/10328749687219979997 2017-02-22T15:12:04+09:00 2017-08-03T16:39:30+09:00 こちらも合わせてどうぞ yutakaseda3216.hatenablog.com はじめに こちらの記事を読んで、最近Unity開発でよく言われるようになった MVPについてだいぶ浸透(あるいは導入)してきたのではないかと思った。 developers.cyberagent.co.jp ただ、すべてのゲームがこの思想でカバーできるかというとそうでもないと思っている。 「そりゃ仕様によって最適解は変わるだろw」と思うかもしれないが 言いたいことはそういうことではなく MVP設計というのは元々Web業界で浸透した設計であり WebのフロントはユーザーがUIを操作するものであるということだ。 つま… <h3>こちらも合わせてどうぞ</h3> <p><iframe class="embed-card embed-blogcard" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" title="【プログラミング】MVC,MVPを理解するためのレイヤーアーキテクチャ - 開発とかメモ。" src="https://hatenablog-parts.com/embed?url=http%3A%2F%2Fyutakaseda3216.hatenablog.com%2Fentry%2F2017%2F08%2F01%2F122801" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://yutakaseda3216.hatenablog.com/entry/2017/08/01/122801">yutakaseda3216.hatenablog.com</a></cite></p> <p> </p> <h3>はじめに</h3> <p>こちらの記事を読んで、最近Unity開発でよく言われるようになった</p> <p>MVPについてだいぶ浸透(あるいは導入)してきたのではないかと思った。</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="Web出身のUnityエンジニアによる大規模ゲームの基盤設計 | CyberAgent Developers Blog | サイバーエージェント デベロッパーズブログ" src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fdevelopers.cyberagent.co.jp%2Fblog%2Farchives%2F4262%2F" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://developers.cyberagent.co.jp/blog/archives/4262/">developers.cyberagent.co.jp</a></cite></p> <p> </p> <p>ただ、すべてのゲームがこの思想でカバーできるかというとそうでもないと思っている。</p> <p> </p> <p>「そりゃ仕様によって最適解は変わるだろw」と思うかもしれないが</p> <p>言いたいことはそういうことではなく</p> <p>MVP設計というのは元々Web業界で浸透した設計であり</p> <p>Webのフロントは<span style="font-size: 150%; color: #d32f2f;">ユーザーがUIを操作する</span>ものであるということだ。</p> <p> </p> <p>つまりこの設計思想をそのまま、あるいは少しのアレンジを加え適用できるのはユーザーがUIを操作することが基本となる</p> <p><span style="color: #d32f2f;">モバイル向け<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B7%A5%E3%A5%EB%A5%B2%A1%BC%A5%E0">ソーシャルゲーム</a>アプリ</span>ということである。</p> <p> </p> <p>それを意識せず、ユーザーがコントローラを持ち、キャラクターを操作するタイプのゲームなど(あくまで、など)で</p> <p> </p> <p>「MVPっていうのがいいらしい」</p> <p>「とりあえず導入しよう」</p> <p> </p> <p>でどこまでがModelでどこまでがViewでPresenterをどこまで定義すれば良いのかが曖昧のまま設計が迷走する例をよく見た。</p> <p> </p> <p>MVPの具体的な活用法に対しては先ほどの記事を読んでもらえばわ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%EB%A4%C8">かると</a>思うので </p> <p>今回はModel-View-Presenterに対して、各レイヤーの解釈について特にUnityゲーム開発における持論を書こうと思う。</p> <p> </p> <p>ある人にとっては間違っているかもしれないが、ある人にとっては正解への道標になるはずだ。</p> <p> </p> <p>先に結論を書くと、Viewは積極的に拡大解釈しろという話だ。</p> <p> </p> <p>あとUniRxとMVPの理解は前提で。</p> <p>  </p> <h3>レイヤーの明確な責任</h3> <p>まずModel-View-Presenterにおける役割を明確にするのと同時に</p> <p>ゲームを作るために必要なレイヤーを全て洗い出す。</p> <p> </p> <h4>MasterData</h4> <p>一応書く。</p> <p>ゲーム中の経験値テーブルや、アイテムのId、価格などのデータ。</p> <p> </p> <h4>Model</h4> <p>ゲームを構成するマスターデータをもとに、ユーザーの現在所持しているアイテム数や、経験値などのいわゆるセーブ対象になるデータを管理しているもの。</p> <p>ゲームを進行するごとに、書き換えられていく。</p> <p> </p> <p>役割として</p> <p> </p> <ol> <li>データを保持する</li> <li>データの書き換えロジックを、メソッドとして外部に公開する</li> <li>データが書き換えられた時、通知を発行する</li> </ol> <p> </p> <p>この役割さえ守っていれば、中身でどれだけ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を生成しようと、どんなロジックを持とうと構わない。</p> <p>逆に言うと、<span style="color: #d32f2f;">これ以外で役割を持ってしまってはいけない。</span></p> <p>そしてModelは依存先を持たず、どんな状態でも自身を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>化できるようにしなければならない。</p> <p> </p> <h4>View</h4> <p>プレイヤーが実際に見る画面と勘違いされやすい(名前的に)。</p> <p>本質的な役割は</p> <p> </p> <ol> <li>ユーザーが実際に見る画面を構成し、表示する</li> <li>画面を更新するメソッドを外部に公開する</li> <li>ユーザーの操作を通知する</li> </ol> <p> </p> <p>最初に書いた通り、UIを操作するだけであるならこのUIが操作されたという通知を飛ばすだけで済む。</p> <p>その通知の結果、Viewの更新を受け取るだけで済むからだ。</p> <p> </p> <p>ただ実際にはそうはいかない。</p> <p>なぜなら、キャラクターを操作できるゲームであるなら、キャラクターの位置が更新され、その結果アイテムを拾えたりする領域に入ったりするなど、複雑であるからだ。</p> <p> </p> <p>そして愚直にMVPに当てはめるのであれば、コントローラ操作というViewが通知を発行し、キャラクターのモデルが位置の変更を通知で管理しなければいけなくなる。</p> <p> </p> <p>はっきり言ってそんな設計は<span style="color: #d32f2f;">冗長すぎてクソ</span>だ。</p> <p>なので後ほどViewの拡大解釈と自由設計について記述する。</p> <p> </p> <p>ただ、上記3つの<span style="color: #d32f2f;">役割自体は変わらないので厳守しなければならない。</span></p> <p>そして、Modelと同じく、Viewはどんな時でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>化可能でなければならない。</p> <p> </p> <h4>Presenter</h4> <p>具体的な機能の提供者である。役割として</p> <p> </p> <ol> <li>Viewからの通知を受け取り、Modelが外部公開しているメソッドを呼ぶ</li> <li>Modelのメソッドを呼んだ結果、Modelからの通知を受け取り、Viewが外部公開しているメソッドを呼ぶ</li> </ol> <p> </p> <p><span style="color: #d32f2f;">単体では機能しないViewとModelをつなげ、ゲームとして成り立つような機能をロジックとして提供する</span></p> <p>となっているが、例として</p> <p> </p> <ol> <li>アイテムを拾える領域に入った通知がViewから飛んでくるので</li> <li>その通知が飛んできた後で他のViewからボタンが押された通知が飛んできたら</li> <li>Modelが公開しているアイテムを一個増やすメソッドを呼び</li> <li>アイテムが増えたという通知を受け取り</li> <li>Viewが公開している「アイテムを拾った演出」を出すメソッドを呼ぶ</li> </ol> <p> </p> <p>という処理を行うといえば、わかりやすいだろうか。</p> <p>Viewが作り込まれれば、あとはPresenterを量産するだけでゲームを拡張していくことが可能になる。</p> <p> </p> <p> </p> <p>以上がレイヤーの責任の話。</p> <p> </p> <p> </p> <h3>Viewを積極的に拡大解釈していく</h3> <p> </p> <p>ここまでの話で、何が一体問題なのかというと</p> <p> </p> <p><span style="color: #d32f2f;">ゲームはユーザーの操作がバリエーション豊富すぎてViewの役割がブレやすい</span></p> <p> </p> <p>というところだ。</p> <p> </p> <p>例として、ゲームの操作キャラクターについての話をした。</p> <p>ここで考えたい</p> <p> </p> <p>キャラクターとはどこのレイヤーに属するのか?</p> <p> </p> <p>ゲームの1機能としてキャラクターを見るのであれば</p> <p>Model-View-Presenterにまたがって処理を書かなければいけない。</p> <p> </p> <p>でも、ユーザーの操作だし、キャラだって要は画面の1要素なのだからView単体で記述しなければいけない。</p> <p> </p> <p>どっちだろうとなる。</p> <p> </p> <p>結論としては、<span style="color: #d32f2f;">どっちも正しい</span></p> <p>なので</p> <p> </p> <p><span style="color: #d32f2f;">Viewとしての役割を厳守できれば、内部の処理はView内で完結されたMVPで記述されても良いのでは</span></p> <p>と考えることも可能である。</p> <p> </p> <p>そしてさらに拡大解釈するなら</p> <p> </p> <p><span style="color: #d32f2f;">Viewとしての役割さえ守れていれば、中身の設計はなんでもいい</span></p> <p> </p> <p>だ。</p> <p> </p> <p>例として、クラス図を書いてみた。</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170222145935p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170222/20170222145935.png" alt="f:id:yutakaseda3216:20170222145935p:plain" /></p> <p> </p> <p>ViewがCharacter全体の各<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>で、ゲームに関連するHpなどをModelに移譲することで見通しが良くなる。</p> <p> </p> <p>CharacterPresenterはCharacterの各<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>の通知を使って、Modelを更新すれば良くなるが、既存のPresenterとは違う点がここで生まれる。</p> <p> </p> <p>それは<span style="color: #d32f2f;">通知を発行したViewは自身で更新を行うということだ。</span></p> <p>ダメージを受けた時に、ダメージモーションの遷移などをいちいちPresenterから発行されていては、Character自身が独立して動かなくなってしまう。</p> <p> </p> <p>なのでPresenterの役割としては</p> <p> </p> <p><span style="color: #d32f2f;">Viewの通知を使い、Modelを更新した結果、必要であれば他のViewに対しての更新を行う</span></p> <p> </p> <p>になる、ダメージの結果HPゲージを更新する処理を呼ぶとかね。</p> <p> </p> <p> </p> <h3>最後</h3> <p> </p> <p>蓋を開けてみればなんだそんなことかと思うかもしれないが</p> <p>責任を明確にしないままMVPを導入するとカオスになるのを身を以て経験している。</p> <p> </p> <p>うまくレイヤーを定義してやり、そのレイヤーに属するものは何なのかを考えよう。</p> <p>そして、責任さえ守れていれば、レイヤーの中身は自由に解釈して構わない</p> <p> </p> <p>そういう結論を今自分では出している。</p> <p> </p> <p> </p> <p>推敲されておらず、勢いだけで書いた文なのでわかりづらいかもしれないが</p> <p> </p> <p> </p> <p>許してね^^</p> <p> </p> <p> </p> <p>何かあれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>までどうぞ。</p> <p> </p> <p>あとこんなこと書いてる暇あるならゲーム作れって言われそうなのでゲーム作ります・・・。</p> <p> </p> yutakaseda3216 UniRxでObservable -> IEnumerator -> Observable変換した時のライフサイクル hatenablog://entry/10328749687219279134 2017-02-20T19:05:05+09:00 2017-02-20T21:01:02+09:00 コード gist9ab1097554ad9f37a8931f82cfdcb467 破棄されない話 .SelectMany()にCoroutineを使用するとうまく破棄されない。 .ToYieldInstruction()を使ってObservable -> IEnumeratorに変換したCoroutineを実行中にコンポーネントを削除するとエラーを吐き出す。 .ToYieldInstruction()したCoroutineはどうやら源流のObservableに紐づけられないようなので 別途.AddTo()でライフサイクルを定義してあげる必要がある CompositeDisposableなどを使… <h3>コード</h3> <p><script src="https://gist.github.com/9ab1097554ad9f37a8931f82cfdcb467.js"> </script></p> <p><a href="https://gist.github.com/9ab1097554ad9f37a8931f82cfdcb467">gist9ab1097554ad9f37a8931f82cfdcb467</a></p> <p> </p> <h3>破棄されない話</h3> <p>.SelectMany()にCoroutineを使用するとうまく破棄されない。</p> <p>.ToYieldInstruction()を使ってObservable -&gt; IEnumeratorに変換したCoroutineを実行中に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>を削除するとエラーを吐き出す。</p> <p> </p> <p>.ToYieldInstruction()したCoroutineはどうやら源流のObservableに紐づけられないようなので</p> <p>別途.AddTo()でライフサイクルを定義してあげる必要がある</p> <p> </p> <p>CompositeDisposableなどを使用したライフサイクル管理をしている場合は</p> <ol> <li>引数でライフサイクルの依存先を渡す</li> <li>Observable.FromCoroutine(_ =&gt; Coroutine()).AddTo(依存先)</li> </ol> <p>でなんとかできるのではないでしょうか。</p> <p> </p> <h3>追記</h3> <p><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/YutaDevelop">@YutaDevelop</a> ToYieldInstructionにCancellationTokenを渡すのが、伝搬方法になっているのですが、SelectManyでは繋ぎにくいですね、一応模範解答はこうですが、面倒くさいのは否めない。 <a href="https://t.co/qPPtEVrtOG">https://t.co/qPPtEVrtOG</a></p>&mdash; neuecc (@neuecc) <a href="https://twitter.com/neuecc/status/833632353847119872">2017年2月20日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p> <p> </p> <p>作者様</p> <p><a href="https://twitter.com/neuecc">neuecc (@neuecc) | Twitter</a></p> <p> </p> <p>よりご回答いただきました、模範解答はこちらのようです。</p> <p> <script src="https://gist.github.com/neuecc/819c30bc297c5b698f5965df62d08fcd.js">// <![CDATA[ // ]]></script> <cite class="hatena-citation"><a href="https://gist.github.com/neuecc/819c30bc297c5b698f5965df62d08fcd">gist.github.com</a></cite></p> <p> </p> <p>CancellationTokenと言う仕組みがあり、引数にそいつを渡してあげることでライフサイクルを定義できるようです。</p> <p><span style="font-size: 80%;">シランカッタ・・・</span></p> <p> </p> <p>使うときはちゃんとオペレータの実装も見ないといかんですね。</p> <p>neuecc様有難うございました。</p> <p> </p> <p> </p> <p>終わり</p> yutakaseda3216 Monodevelop - UnityでVersionControlが消えた時の対処 hatenablog://entry/10328749687205655405 2017-01-11T11:31:54+09:00 2017-01-11T11:32:37+09:00 はじめに MacOSX 10.11.2 Unity 5.4.2f2 MonoDevelop-Unity 5.9.6 バージョン管理はGit BlameやDiff、Changesをワンクリックで見れるので重宝してる、こんなやつ ただこいつはよく消える 消えた時 Monodevelop-Unity > Add-In Managerを開いてこれをenableにする これで復活 する時もあればしない時もある しない時はSolutionWindowを開いて(View > Pads > Solutionで開ける) スクリプトファイルを選択した時に出る歯車アイコンクリック、DiffとかBlameとかLogと… <p> </p> <h4>はじめに</h4> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MacOSX">MacOSX</a> 10.11.2</p> <p>Unity 5.4.2f2</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MonoDevelop">MonoDevelop</a>-Unity 5.9.6</p> <p>バージョン管理はGit</p> <p> </p> <p>BlameやDiff、Changesをワンクリックで見れるので重宝してる、こんなやつ</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170111112414p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170111/20170111112414.png" alt="f:id:yutakaseda3216:20170111112414p:plain" /></p> <p> </p> <p>ただこいつはよく消える</p> <p> </p> <h4>消えた時</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Monodevelop">Monodevelop</a>-Unity &gt; Add-In Managerを開いてこれをenableにする</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170111112604p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170111/20170111112604.png" alt="f:id:yutakaseda3216:20170111112604p:plain" /></p> <p> </p> <h4>これで復活</h4> <p>する時もあればしない時もある</p> <p>しない時はSolutionWindowを開いて(View &gt; Pads &gt; Solutionで開ける)</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ファイルを選択した時に出る歯車アイコンクリック、DiffとかBlameとかLogとか選択すると復活する</p> <p> </p> <p>それでも復活しなかった時が来たら対処法調べて追記します。</p> yutakaseda3216 【windows】何も考えずに最速でsshkeyを作ってgithubと連携する hatenablog://entry/10328749687203836334 2017-01-05T21:27:54+09:00 2017-01-05T21:27:54+09:00 Gitをインストールします Git - Downloading Package 各チェックボックスはこんな感じで 後は全部一番上にして、デフォルトのままでおk インストール後 デスクトップにできたGitBashのアイコンをダブルクリックでBash開く sshkeyを作る(下記をそのまま打ち込んでEnter) ssh-keygen ここに作りますか?って聞かれる。(ディレクトリ階層が表示されてる) Enter押す passphraseは?って聞かれる。何も考えないのでいらない Enter押す もういっかい入力してねって言われる。何もいれてないのでいらない Enter押す GitHubと連携 ss… <h3>Gitをインストールします</h3> <p><a href="https://git-scm.com/download/win">Git - Downloading Package</a></p> <h5>各<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%A7%A5%C3%A5%AF%A5%DC%A5%C3%A5%AF%A5%B9">チェックボックス</a>はこんな感じで</h5> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170105211036p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170105/20170105211036.png" alt="f:id:yutakaseda3216:20170105211036p:plain" /></p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170105211116p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170105/20170105211116.png" alt="f:id:yutakaseda3216:20170105211116p:plain" /></p> <p>後は全部一番上にして、デフォルトのままでおk</p> <p> </p> <h3>インストール後</h3> <p>デスクトップにできたGitBashのアイコンをダブルクリックで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Bash">Bash</a>開く</p> <p>sshkeyを作る(下記をそのまま打ち込んでEnter)</p> <p><span style="font-size: 200%;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>-keygen</span></p> <p>ここに作りますか?って聞かれる。(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リ階層が表示されてる)</p> <p>Enter押す</p> <p>passphraseは?って聞かれる。何も考えないのでいらない</p> <p>Enter押す</p> <p>もういっかい入力してねって言われる。何もいれてないのでいらない</p> <p>Enter押す</p> <p> </p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>と連携</h3> <p>sshkeyは初期状態のままならUser/自分のアカウント名/.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>フォルダ内にある</p> <p>隠しフォルダになってる場合があるので隠しフォルダ見えるようにしとこう</p> <p>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>フォルダの中にある、id_<a class="keyword" href="http://d.hatena.ne.jp/keyword/rsa">rsa</a>.pubを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C6%A5%AD%A5%B9%A5%C8%A5%A8%A5%C7%A5%A3%A5%BF">テキストエディタ</a>で開くと謎の文字列が生成されているのですべてコピーする</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170105212411p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170105/20170105212411.png" alt="f:id:yutakaseda3216:20170105212411p:plain" /></p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a>開いて、右上の自分のアイコンからSettingsを選択するとこんな画面が出る。</p> <p>その中の<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a> and GPG keysを選択</p> <p> </p> <p>New <a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a> Keyボタンを押してこんな感じで作成</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20170105212610p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20170105/20170105212610.png" alt="f:id:yutakaseda3216:20170105212610p:plain" /></p> <p>後は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>クローンするときに<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>でクローンして快適なgitライフを送ろう!</p> <p> </p> <h4>終わり</h4> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/CUI">CUI</a>慣れてからSourceTreeとかKrakenとかの<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>に移行しないとgitの内部的な動作ちんぷんかんぷんで終わるので気を付けような(もちろん内部知らなくていいよって人はKrakenをぜひオヌヌヌします)</p> yutakaseda3216 コミケに参加して&SleepWalkerの今後 hatenablog://entry/10328749687202073489 2016-12-29T23:57:13+09:00 2016-12-29T23:57:13+09:00 はじめに PhantomIslandのブースまで、朝早くに来てくださった方、ご購入していただいた方 大変ありがとうございました。 動画を見ましたと言ってくれる方や、デジゲー博でプレイしていただいていた方など、多くの方に直接販売することができました。 私は、人に直接モノを売るというのが初めての経験でしたので、とてもうれしかったです。 30枚の用意でしたが、午前中早々に完売してしまい、ゲームを目当てにブースに来てくださった方に完売してしまいましたというのが心苦しかったです、数を用意できず申し訳ありません。 しかし海外の方が数名いらしていただいた際に、買えなかったですが今後に期待していますと言われ、… <h4> </h4> <h4>はじめに</h4> <p>PhantomIslandのブースまで、朝早くに来てくださった方、ご購入していただいた方</p> <p>大変ありがとうございました。</p> <p>動画を見ましたと言ってくれる方や、デジゲー博でプレイしていただいていた方など、多くの方に直接販売することができました。</p> <p>私は、人に直接モノを売るというのが初めての経験でしたので、とてもうれしかったです。</p> <p>30枚の用意でしたが、午前中早々に完売してしまい、ゲームを目当てにブースに来てくださった方に完売してしまいましたというのが心苦しかったです、数を用意できず申し訳ありません。</p> <p>しかし海外の方が数名いらしていただいた際に、買えなかったですが今後に期待していますと言われ、とても身が引き締まる思いでした。</p> <p>ありがとうございました。</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%DF%A5%B1">コミケ</a>の活気はすごいですね!デジゲー博の時も思いましたが、素晴らしい場だと思います。</p> <p>参加できて本当によかったです。</p> <p> </p> <h4>頒布したもの</h4> <p>今回頒布した体験版ですが</p> <p>・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%EF%A1%BC%A5%EB%A5%C9">オープンワールド</a>で自由に探索(本編)</p> <p>・ボスとの戦闘モード</p> <p>の二種類のモードをつけさせていただきました。</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%EF%A1%BC%A5%EB%A5%C9">オープンワールド</a>では、様々な人と話をしたり、依頼をこなしたり、広大な世界を探索できます。</p> <p>ボスとの戦闘は、一筋縄ではいかないものを用意させていただきました。</p> <p>ご購入された方はぜひお楽しみください。</p> <p> </p> <h4>今後のSleepWalker</h4> <p> </p> <p>製品版としては、まだまだ未完成な部分も多く、システムすら乗っていないものもあります。</p> <p>完成は来年の夏を予定していますが、その前に一度展示をしようと思っています。</p> <p>BitSummitへの申し込みを予定していますが、予定は未定です。</p> <p> </p> <p>また、今回の体験版で数多くの課題が出ました。</p> <p>それを一つずつ潰していこうと思っています。</p> <p> </p> <p>また。製品版へ追加するシステムはこのようになっています</p> <p>・キャラクターの強化システムの作成</p> <p>・敵キャラクターの追加</p> <p>・必殺技追加</p> <p>・攻撃技の追加</p> <p>・新たに6ワールド追加、7つの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%F3">ダン</a>ジョンを作成</p> <p>・アイテムの追加</p> <p>・装備品(装飾品)の追加</p> <p> </p> <p>キャラクターを育てる、世界をより仕上げていく、という部分をこれから開発していきます。</p> <p>ご期待いただければ幸いでございます。</p> <p> </p> <h4>最後に</h4> <p>同人で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%EF%A1%BC%A5%EB%A5%C9">オープンワールド</a>ゲームを開発しているということで、国内外で少しだけ注目していただけているようです。</p> <p>少しプレッシャーもありますが、周りの開発者さんががんばっているところを見て、自分も頑張ろうという気持ちになれています。</p> <p>ありがとうございます、これからもよろしくお願いいたします。</p> <p> </p> <p>ゲームの完成をお楽しみに!</p> yutakaseda3216 UnityでGitLFSを使用する際にTrackするべきファイル hatenablog://entry/10328749687201331397 2016-12-26T14:36:51+09:00 2017-03-10T14:27:29+09:00 リポジトリが爆発したので背に腹は変えられないとLFSの導入を決意 Trackする画像や素材拡張子 *.png *.psd *.tga *.jpg *.fbx *.anim *.mp3 *.ogg *.wav git lfs track *.~するより、.gitattributesに直接記述した方が早い 追記(2017/03/10) .animはアニメーション編集しない前提なので、編集する場合は.animを管理対象から外した方が良い 結果 導入前:リポジトリ9GB 導入後:リポジトリ1.2GB(!!!!) LFS 6GB なんか差分の1GBくらいどっかいったけど、多分履歴をfilterしたりした… <p> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>が爆発したので背に腹は変えられないと<a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a>の導入を決意</p> <h4>Trackする画像や素材拡張子</h4> <p>*.<a class="keyword" href="http://d.hatena.ne.jp/keyword/png">png</a></p> <p>*.psd</p> <p>*.tga</p> <p>*.jpg</p> <p>*.fbx</p> <p>*.anim</p> <p>*.mp3</p> <p>*.<a class="keyword" href="http://d.hatena.ne.jp/keyword/ogg">ogg</a></p> <p>*.wav</p> <p> </p> <p>git <a class="keyword" href="http://d.hatena.ne.jp/keyword/lfs">lfs</a> track *.~するより、.gitattributesに直接記述した方が早い</p> <p> </p> <p><strong>追記(2017/03/10)</strong></p> <p>.animはアニメーション編集しない前提なので、編集する場合は.animを管理対象から外した方が良い</p> <p> </p> <h4>結果</h4> <p>導入前:<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>9GB</p> <p>導入後:<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>1.2GB(!!!!) <a class="keyword" href="http://d.hatena.ne.jp/keyword/LFS">LFS</a> 6GB</p> <p> </p> <p>なんか差分の1GBくらいどっかいったけど、多分履歴をfilterしたりしたから?</p> <p>バイナリ直で持たなくなったから減るとかあるのかな</p> <p> </p> <p>うまく使ってBitBucket無料プランで乗り切っていきたい</p> <p> </p> <p>あと<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSH">SSH</a>認証じゃないとファイル100件ごとにパスワード要求されるのでKeyは作っておこう</p> yutakaseda3216 デジゲー博お疲れさまでした&SleepWalkerデモ版配布 hatenablog://entry/10328749687194238122 2016-11-13T21:22:14+09:00 2016-11-14T21:10:24+09:00 どうも、かせです。 本日、デジゲー博にSleepWalkerのデモ版を出展させていただきました。 会場から閉会まで絶え間なくプレイしていただき、デジゲー博の熱量の高さを思い知りました。 また、夏から開発しはじめ、初めて人前でプレイをしていただけたので、様々なフィードバックを得ることができました。 この場を借りて デジゲー博準備会様 各出展者様 来場者様 に深く感謝の意を述べさせていただきたく思います。 また、ゲームライターコミュニティ様にて記事を書いていただきました。 【デジゲー博2016】SleepWalker – ゲームライターコミュニティ ありがとうございました。 SleepWalker… <p> </p> <p>どうも、かせです。</p> <p> </p> <p>本日、デジゲー博にSleepWalkerのデモ版を出展させていただきました。</p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20161113205901p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20161113/20161113205901.png" alt="f:id:yutakaseda3216:20161113205901p:plain" /></p> <p>会場から閉会まで絶え間なくプレイしていただき、デジゲー博の熱量の高さを思い知りました。</p> <p> </p> <p>また、夏から開発しはじめ、初めて人前でプレイをしていただけたので、様々なフィードバックを得ることができました。</p> <p>この場を借りて</p> <p>デジゲー博準備会様</p> <p>各出展者様</p> <p>来場者様</p> <p>に深く感謝の意を述べさせていただきたく思います。</p> <p> </p> <p>また、ゲームライターコミュニティ様にて記事を書いていただきました。</p> <p><a href="https://t.co/CgaXsxY0Vk">【デジゲー博2016】SleepWalker – ゲームライターコミュニティ</a></p> <p>ありがとうございました。</p> <p> </p> <h3>SleepWalkerについて</h3> <p>夏から開発をしている「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%EF%A1%BC%A5%EB%A5%C9">オープンワールド</a>3D<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%AF%A5%B7%A5%E7%A5%F3RPG">アクションRPG</a>」です。</p> <p>世界の体験をコンセプトとして、開発をしています。</p> <p>また、プレイ感覚としてリアルな感覚を追求するのではなく</p> <p>より爽快、かつなめらかなアクションを目指しています。</p> <p> </p> <p>今回のデモは、アクション部分のコンセプトモデルでした。</p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20161113210515p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20161113/20161113210515.png" alt="f:id:yutakaseda3216:20161113210515p:plain" /></p> <p> </p> <p><img class="hatena-fotolife" title="f:id:yutakaseda3216:20161113210625p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/y/yutakaseda3216/20161113/20161113210625.png" alt="f:id:yutakaseda3216:20161113210625p:plain" /></p> <p> </p> <p>このデモ版の配布をさせていただきます。</p> <p> </p> <p><a href="https://www.dropbox.com/s/nhvly8vbzkiydd5/sleepwalker.zip?dl=0">Dropbox - sleepwalker.zip</a></p> <p> </p> <p>操作方法</p> <p> </p> <p>「移動」左スティック</p> <p>「視点移動」右スティック</p> <p>「会話」Bボタン</p> <p>「ジャンプ」Aボタン</p> <p>「飛行」ジャンプ中にAボタンを再度押す、押しっぱなしで持続</p> <p>「弱攻撃」地上・空中でXボタン</p> <p>「強攻撃」地上・空中でYボタン</p> <p>「打ち上げ」地上でRトリガーをおしながらXボタン</p> <p>「追撃」地上・空中でRトリガーをおしながらYボタン</p> <p>「回避」Rトリガーボタン</p> <p> </p> <p>打ち上げ、追撃はすべての行動をキャンセルすることができます。</p> <p>かっこいいコンボができると気持ちいいです。</p> <p> </p> <p>動作環境</p> <p> </p> <p>そこそこのグラフィックスカードがあれば、ラップトップでも30FPSで動作すると思います。</p> <p>また、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%E0%A5%D1%A5%C3%A5%C9">ゲームパッド</a>はXInput対応のもののみのサポートになります。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Xbox360">Xbox360</a>コントローラ、XboxOneコントローラの動作は確認済みです。</p> <p>ご意見などございましたら、気軽に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>の方でお声がけください。</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="かせ (@YutaDevelop) | Twitter" src="//hatenablog-parts.com/embed?url=https%3A%2F%2Ftwitter.com%2FYutaDevelop" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="https://twitter.com/YutaDevelop">twitter.com</a></cite></p> <p> </p> <h3>今後について</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%DF%A5%B3%A5%DF">冬コミ</a>に当選しました。</p> <p><strong>1日目・西"ひ"-13a</strong></p> <p>でSleepWalkerの</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%EF%A1%BC%A5%EB%A5%C9">オープンワールド</a>になってる(する)</p> <p>ボス戦とか実装した(する)</p> <p>体験版を頒布予定です。</p> <p> </p> <p>少しでも魅力を感じていただけましたら、ぜひご来場くだされば幸いです。</p> <p>よろしくお願い致します。</p> <p> </p> <h3>最後に</h3> <p>ゲームを面白くするために努力してまいりますので、ぜひSleepWalkerの完成をお楽しみに!</p> yutakaseda3216 UniRxを紐解く「Take(1)とFirst()の違い」 hatenablog://entry/10328749687191496578 2016-10-27T11:25:34+09:00 2019-02-15T15:38:02+09:00 UniRxとは 大変便利なReactiveExtensionsのUnity版ライブラリ。 neue cc neuecc (@neuecc) | Twitter 最近、業務でも業務外でもこちらを触ることが多く、色々な地雷を踏み倒してきました。 備忘録の意味も兼ねて今回は 「Take(1)とFirst()」の違い をまとめようと思います。 入門者向きではないです、ご了承ください。 あとかなり長いです。 ソースコードなどはこちらの qiita.com を参考にさせていただいています。 TakeとかFirstってなんですか?という方は、こちらをまず読まれると良いと思います。 その他にも様々な分かりやす… <h4>UniRxとは</h4> <p>大変便利なReactiveExtensionsのUnity版ライブラリ。</p> <p><a href="http://neue.cc/">neue cc</a></p> <p><a href="https://twitter.com/neuecc/">neuecc (@neuecc) | Twitter</a></p> <p> </p> <p>最近、業務でも業務外でもこちらを触ることが多く、色々な地雷を踏み倒してきました。</p> <p>備忘録の意味も兼ねて今回は</p> <ul> <li>「Take(1)とFirst()」の違い</li> </ul> <p>をまとめようと思います。</p> <p>入門者向きではないです、ご了承ください。</p> <p>あとかなり長いです。</p> <p> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>などはこちらの</p> <p><iframe class="embed-card embed-webcard" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" title="UniRxのシンプルなサンプル その3(FirstとTake) - Qiita" src="//hatenablog-parts.com/embed?url=http%3A%2F%2Fqiita.com%2FMarimoiro%2Fitems%2Fb24510b0ffd273f69f8a" frameborder="0" scrolling="no"></iframe><cite class="hatena-citation"><a href="http://qiita.com/Marimoiro/items/b24510b0ffd273f69f8a">qiita.com</a></cite></p> <p>を参考にさせていただいています。</p> <p>TakeとかFirstってなんですか?という方は、こちらをまず読まれると良いと思います。</p> <p>その他にも様々な分かりやすいサンプルがあり、入門に最適です。 </p> <p> </p> <h3> Take(n)</h3> <p>nに指定した分だけ、OnNextを発行するオペレータです。</p> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UnityEngine</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">System.Collections</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx.Triggers</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="nc" style="box-sizing: border-box; color: #445588; font-weight: bold;">TakeSample</span> <span class="p" style="box-sizing: border-box;">:</span> <span class="n" style="box-sizing: border-box; color: #333333;">Base</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">// Use this for initialization</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="nf" style="box-sizing: border-box; color: #990000; font-weight: bold;">Start</span> <span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="n" style="box-sizing: border-box; color: #333333;">gameObject</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">transform</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">position</span> <span class="p" style="box-sizing: border-box;">=</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">new</span> <span class="n" style="box-sizing: border-box; color: #333333;">Vector2</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0.5f</span><span class="p" style="box-sizing: border-box;">);</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">//Takeで最初の100回以外はカット</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">this</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">UpdateAsObservable</span><span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Take</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">100</span><span class="p" style="box-sizing: border-box;">)</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Subscribe</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Move</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0.01f</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">));</span> <span class="p" style="box-sizing: border-box;">}</span> <span class="p" style="box-sizing: border-box;">}</span></pre> <p> この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>上で書かれたObservableを分解すると</p> <p> </p> <ul> <li><span style="color: #ff0000;">this.UpdateAsObservable()</span></li> </ul> <p>毎フレーム、次のオペレータ[Take(100)]に対してOnNextを発行する</p> <ul> <li><span style="color: #ff0000;">.Take(100)</span></li> </ul> <p>OnNextを100回だけ次のオペレータに発行する</p> <ul> <li><span style="color: #ff0000;">Subscribe(l =&gt; Move(0.01f,0));</span></li> </ul> <p>OnNextが来たら、Move(0.01f,0)を叩く</p> <p> </p> <p>という記述がされています。</p> <p> </p> <p>ここでさらに、記述されていない中身を付け足した<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>がこちらです</p> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UnityEngine</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">System.Collections</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx.Triggers</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="nc" style="box-sizing: border-box; color: #445588; font-weight: bold;">TakeSample</span> <span class="p" style="box-sizing: border-box;">:</span> <span class="n" style="box-sizing: border-box; color: #333333;">Base</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">// Use this for initialization</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="nf" style="box-sizing: border-box; color: #990000; font-weight: bold;">Start</span> <span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="n" style="box-sizing: border-box; color: #333333;">gameObject</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">transform</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">position</span> <span class="p" style="box-sizing: border-box;">=</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">new</span> <span class="n" style="box-sizing: border-box; color: #333333;">Vector2</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0.5f</span><span class="p" style="box-sizing: border-box;">);</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">//Takeで最初の100回以外はカット</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">this</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">UpdateAsObservable</span><span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Take</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">100</span><span class="p" style="box-sizing: border-box;">)</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Subscribe</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Move</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0.01f</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">),<br /> () =&gt; OnCompleted());</span> <span class="p" style="box-sizing: border-box;">}</span> <span class="p" style="box-sizing: border-box;">}</span></pre> <p> </p> <p>() =&gt; OnCompleted()がSubscribeに追加されています。</p> <p>これは、Subscribeまでのストリームで、OnCompletedが発行された際に実行されます。</p> <p> </p> <p>そして、今回のObservableでOnCompletedを発行するのは</p> <p><span style="color: #ff0000;">Take(100)が100回OnNextを通した時です。</span></p> <p> </p> <p>つまるところ、100回Move()したら、OnCompletedが呼ばれるということです。</p> <p> </p> <p>ちなみに、OnCompletedはだいたいどのオペレータでも</p> <ul> <li>try { observer.OnCompleted() }  finally { Dispose(); } ;</li> </ul> <p>という処理になっていますので、OnCompletedを発行してエラーを吐いてもDisposeされるようになっています。</p> <p> </p> <h5>まとめ</h5> <p>Take(n)はnに指定した回数だけOnNextを通して、終了時にOnCompletedを発行する</p> <p> </p> <h3>First(Func),First()</h3> <p>OnNextが発行された最初の一度だけOnNextを発行します</p> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UnityEngine</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">System.Collections</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">using</span> <span class="nn" style="box-sizing: border-box; color: #555555;">UniRx.Triggers</span><span class="p" style="box-sizing: border-box;">;</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="nc" style="box-sizing: border-box; color: #445588; font-weight: bold;">First</span> <span class="p" style="box-sizing: border-box;">:</span> <span class="n" style="box-sizing: border-box; color: #333333;">Base</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">// Use this for initialization</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="nf" style="box-sizing: border-box; color: #990000; font-weight: bold;">Start</span><span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="n" style="box-sizing: border-box; color: #333333;">gameObject</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">transform</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">position</span> <span class="p" style="box-sizing: border-box;">=</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">new</span> <span class="n" style="box-sizing: border-box; color: #333333;">Vector2</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">1f</span><span class="p" style="box-sizing: border-box;">);</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">//クリックされたら右に1.5動かす(但し1回だけ)</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">this</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">UpdateAsObservable</span><span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">First</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Input</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">GetMouseButton</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">))</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Subscribe</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Move</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">1.5f</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">));</span></pre> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;"> //こっちもやってること同じ<br /></span><span class="k" style="box-sizing: border-box; font-weight: bold;"> this</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">UpdateAsObservable</span><span class="p" style="box-sizing: border-box;">()<br /></span> .Where(_ =&gt; Input.GetMouseButton(0))<br /><span class="p" style="box-sizing: border-box;"> .</span><span class="n" style="box-sizing: border-box; color: #333333;">First</span><span class="p" style="box-sizing: border-box;">(</span><span class="p" style="box-sizing: border-box;">)<br /></span><span class="p" style="box-sizing: border-box;"> .</span><span class="n" style="box-sizing: border-box; color: #333333;">Subscribe</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Move</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">1.5f</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">));<br /></span><span class="p" style="box-sizing: border-box;">}</span> <span class="p" style="box-sizing: border-box;">}</span></pre> <p> この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>上で書かれたObservableをまた分解していきます</p> <p style="line-height: 1.5; margin: 0.5em 0px; padding: 0px; color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> </p> <ul style="color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> <li><span style="color: #ff0000;">this.UpdateAsObservable()</span></li> </ul> <p>毎フレーム、次のオペレータ[First(Func)]に対してOnNextを発行する</p> <ul style="color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> <li><span style="color: #ff0000;">.First(Func) .First()</span></li> </ul> <p>OnNextをFuncがtrueの時に、一度発行する</p> <p>FuncがないFirst()は、OnNextを無条件で発行する</p> <ul style="color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> <li><span style="color: #ff0000;">Subscribe(l =&gt; Move(0.01f,0));</span></li> </ul> <p>OnNextが来たら、Move(0.01f,0)を叩く</p> <p> </p> <p>という記述がされています。</p> <p style="line-height: 1.5; margin: 0.5em 0px; padding: 0px; color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> </p> <p>First()は一度OnNextを発行すると、OnCompletedを発行します</p> <p style="line-height: 1.5; margin: 0.5em 0px; padding: 0px; color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="color: #ff0000;">単体では、Take(1)と同じ挙動をします</span></p> <p style="line-height: 1.5; margin: 0.5em 0px; padding: 0px; color: #3d3f44; font-family: 'Helvetica Neue', Helvetica, Arial, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', メイリオ, Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> </p> <h5>まとめ</h5> <p>First(),First(Func)は一回OnNextを発行し、その後OnCompletedを発行する</p> <p> </p> <h3>Take(1)とFirst()の違い</h3> <p> ここまで読んで</p> <p>「Take()は回数指定できる、First()は条件指定できるのね、へ〜」</p> <p> と思ったことでしょう。</p> <p> </p> <p>それだけではないです、というかここからが重要です</p> <p>端的に言うと</p> <p><span style="color: #ff0000;">OnCompletedをオペレータ内で通す際の挙動</span>に明確な違いがあります</p> <p> </p> <p>TakeとFirstのOnCompletedメソッドをごらんください</p> <ul> <li>Take</li> </ul> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="color: #333333; font-weight: normal;"><span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> </span><span style="color: #445588;"><strong style="font-weight: bold;">Take</strong></span> <span class="p" style="box-sizing: border-box;">:</span><span style="color: #333333;"> OperatorObserverbase&lt;T,T&gt;</span><span class="p" style="box-sizing: border-box;">{<br /><br /> public override void OnCompleted(){<br /> try {observer.OnCompleted();} finally { Dispose(); }<br /> }<br /><br /></span>}</pre> <ul> <li>First</li> </ul> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="color: #333333; font-weight: normal;"><span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> </span><span style="color: #445588;"><strong>First</strong></span> <span class="p" style="box-sizing: border-box;">:</span><span style="color: #333333;"> OperatorObserverbase&lt;T,T&gt;</span><span class="p" style="box-sizing: border-box;">{<br /><br /> public override void OnCompleted(){<br /> if(notPublished){<br /> try { observer.OnError(new InvalidOperationException("Sequence is empty"));}<br /> finally { Dispose(); }<br /> }<br /> else{<br /> try {observer.OnCompleted();} finally { Dispose(); }<br /></span> }<br /> }<br />}</pre> <p> </p> <p>こうなってます、全然違いますね。</p> <p> </p> <p>一目見てなんだこれとなるのは、First()の方にあるnotPublishedというboolだと思います。</p> <p><span style="color: #ff0000;">これはFirst()でOnNextが発行された時にfalseになるbool値です。</span></p> <p>OnNextメソッドでもこれを使用していて、notPublishedの状態の時のみOnNextが次のオペレータに発行されるようになっています。</p> <p>一度だけしか発行しない処理の中身はこうなっていました。</p> <p> </p> <p>つまり</p> <h5><span style="color: #ff0000;">OnNextが一度も通っていないFirstオペレータはOnCompletedを通しません</span></h5> <p>こういう明確な差があるわけですね。</p> <p> </p> <p>例として</p> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="k" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="nc" style="box-sizing: border-box; color: #445588; font-weight: bold;">First</span> <span class="p" style="box-sizing: border-box;">:</span> <span class="n" style="box-sizing: border-box; color: #333333;">Base</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">// Use this for initialization</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="nf" style="box-sizing: border-box; color: #990000; font-weight: bold;">Start</span><span class="p" style="box-sizing: border-box;">()</span> <span class="p" style="box-sizing: border-box;">{</span> <span class="n" style="box-sizing: border-box; color: #333333;">gameObject</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">transform</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">position</span> <span class="p" style="box-sizing: border-box;">=</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">new</span> <span class="n" style="box-sizing: border-box; color: #333333;">Vector2</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">1f</span><span class="p" style="box-sizing: border-box;">);</span> <span class="c1" style="box-sizing: border-box; color: #999988; font-style: italic;">//クリックされたら右に1.5動かす(但し1回だけ)</span> <span class="k" style="box-sizing: border-box; font-weight: bold;">this</span><span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">UpdateAsObservable</span><span class="p" style="box-sizing: border-box;">()<br /></span> .TakeWhile(_ =&gt; isEnabled)<br /> .Where(_ =&gt; Input.GetMouseButton(0)) <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">First</span><span class="p" style="box-sizing: border-box;">(</span><span class="p" style="box-sizing: border-box;">)</span> <span class="p" style="box-sizing: border-box;">.</span><span class="n" style="box-sizing: border-box; color: #333333;">Subscribe</span><span class="p" style="box-sizing: border-box;">(</span><span class="n" style="box-sizing: border-box; color: #333333;">l</span> <span class="p" style="box-sizing: border-box;">=&gt;</span> <span class="n" style="box-sizing: border-box; color: #333333;">Move</span><span class="p" style="box-sizing: border-box;">(</span><span class="m" style="box-sizing: border-box; color: #009999;">1.5f</span><span class="p" style="box-sizing: border-box;">,</span> <span class="m" style="box-sizing: border-box; color: #009999;">0</span><span class="p" style="box-sizing: border-box;">));</span></pre> <pre style="box-sizing: border-box; overflow: auto; font-size: 0.8em; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; display: block; margin: 0px; padding: 0.6em 1.2em; border: 0px; border-radius: 3px; background-color: #f7f7f7; color: #333333; word-wrap: normal; word-break: break-all; line-height: 1.2; white-space: pre; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="p" style="box-sizing: border-box;">}</span> <span class="p" style="box-sizing: border-box;">}</span></pre> <p>このコードで</p> <p>一度もGetMouseButton(0)がtrueにならないまま、isEnabledがfalseになり</p> <p>OnCompletedが発行されると、FirstくんはErrorを吐きます。</p> <p> </p> <p> </p> <h3>まとめ</h3> <p>OnNextが発行されていなくてもOnCompletedを次のオペレータに通知できるのが</p> <p>Take(1)</p> <p>OnNextが発行されていないと、OnCompletedを次のオペレータに通知できないのが</p> <p>First()</p> <p>です。</p> <p> </p> <p>もしOnCompletedを発行できるオペレータが複数あるストリームを組むときは</p> <p>Take(1)を使用することを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%CC%A5%CC%A5%E1">オヌヌメ</a>します。</p> <p> </p> <p>終わり。</p> <p>間違いなどがあったら@YutaDevelopまでお願いします。</p> <p> </p> <p>unirxすげー</p> <p> </p> yutakaseda3216