勉強会のレポート(メモ)です。
参加したのはこちら、「.NET Conf in Tokyo 2019」
会場はマイクロソフトさんです。
ハッシュタグは3種類あります。
共通 : #dotnetconf
.NET Track : #dotnetconfdotnet
Unity Track : #dotnetconfunity
本イベントは.NETに関する.NET TrackとUnityに関するUnity Trackの2つに分かれています。
このレポではUnity Trackをメインでお送りします。
Room B (Unity Track)
時間 | タイトル | 発表者 |
---|---|---|
11:00-11:05 | Opening .NET Conf 2019 in Tokyo | Hiroyuki Mori (@hiroyuki_mori) |
11:00-12:20 | What’s New in .NET Core 3.0 and Visual Studio 2019 for .NET developers(サテライト会場) | Steve Carroll |
13:20-14:10 | Clean Architecture for Unity | Tetsuya Mori (@monry) |
14:20-15:10 | MagicOnion〜C#でゲームサーバを開発しよう〜 | torisoup (@toRisouP) |
15:30-16:20 | Riderはいいぞ! | Ryota Murohoshi (@RyotaMurohoshi) |
16:30-17:20 | C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜 | ユニティ・テクノロジーズ・ジャパン 安原祐二・名雪通 |
17:20-17:30 | Closing | Tetsuya Mori (@monry) and torisoup (@toRisouP) |
- Room B (Unity Track)
#1. Clean Architecture for Unity
.NET Conf Tokyo にて「Clean Architecture for Unity」というタイトルで発表しました。 #cleanarchitecture #unity #dotnetconf #dotnetconfunity https://t.co/bud3IzHGcV @SlideShareさんから
— もんりぃ先生 (@monry) October 27, 2019
対象者
Unityでもしっかりと設計したい人
Clean Architectureの導入事例を聞きたい人
マサカリを研いでいない人
話すこと
設計に関する基本
Clean Architectureの例の図
Unityに適応してみた話
オススメ資料
世界一わかりやすいClean Architecture
お仕事の宣伝
キッズスターでごっこランドという職業体験アプリを作っています
ここで得た知見をお話します
Clean Architectureとは
厳密に定義されたものは存在しません。ざっくりとした指針はあります。
みんなが思う最高のClean Architectureを作りましょう
この図を見たことはありますか?
この図にはいろいろ書かれていますがこれは一例です。
抑えるポイントを守ると自然とこの図になります。今日はこのポイントを覚えて帰ってください。
SOLID原則とDI
Clean Architectureと切っては切れないもの。
SOLID原則は保守性の高いソフトウェアを開発運用する上で基本となる考え方。
守れば保守性の高いコードが書けます。
SOLID原則とは何か
5つの原則をまとめたものです。
単一責任原則
クラスが担う責務は一つだけにしなさいというルール。
なんちゃらManagerやなんちゃらControllerなど主語がでかい名前をつけるとこれを守りづらくなります。
責務が狭い名前をつけましょう。
オープンクローズド原則
拡張に開いて修正に閉じる。
拡張しやすく、ただしそれぞれのメソッドに修正が発生しないようにすること。
インターフェースやアブストラクトを使いましょう。
リスコフの置換原則
親クラスと子クラスは置換可能であるということ。
C#の場合、newによる上書きで違反しやすい。
インターフェース分離の法則
いらないメソッド・プロパティは実装しないさせないこと。
C#は複数インターフェースを実装できるが、これらのインターフェースは分離しましょう。
ここは単一責任原則にもつながるところ。
多機能なインターフェースを実装すると破られます。
依存性逆転の原則
一番重要
抽象に依存し実装に依存させないということ。
ざっくりいうとインターフェースを引数にとり、実クラスには関心を持たせない。
DIはこれを実現するためにある。
Dependency Injection(DI)
依存性逆転を実現させるためにあるもの。
UnityではZenjectが有名。Mono Behaviourへの注入をいい感じにやってくれる。
Mono BehaviourはnewができないしPropertyをInjectionすることができない。
そこをZenjectが裏で頑張っていい感じにやってくれます。
Zenjectの場合、Installerでルールを定義できるようになっています。
詳しくはZenjectチョットワカルBookがおすすめ
もんりぃ先生の発表の途中で出てきたZenjectチョットワカルBookは入門するのにはいい感じな気がするのでオススメします(ダイレクトマーケティング)https://t.co/vtpjt5fyuW#dotnetconfunity
— いも@ZenjectチョットワカルBook (@adarapata) October 27, 2019
UnityにおけるClean Architectureをどう実現するか
Clean Architectureは2012年にロバート・C. マーチンさんがブログで発表したもので
ざっくりとした方針だけ定義しました。
方針はこの2つ
・依存の向きは外から内のみ
・制御の流れは依存と切り分けて考える
依存の向きとは何か
図の矢印の向きのこと。
外から内にのみ向くようにしましょう。
ちなみに図にある名前は、あくまで目安です。そういう名前にしなさいというものではない。
制御の流れ
データの流れは内から外にだが制御の流れはどっちでも大丈夫。
内から外にいくのは割とシンプルになるが、入力はObserberパターンを使わないとしんどくなる。
なぜクリーンアーキテクチャをつかうのか
注意、こっからは一例です。
ごっこランドには50個以上のミニゲームが入っています。
それぞれのミニゲームは1つ1つのUnityプロジェクトであり、最後に1つのプロジェクトにマージ。
いろいろな人が開発にかかわるが、書き方を統一したかった。
導入したメリット
疎結合、テスタビリティが高い
慣れると可読性が高い
デメリット
インターフェース、クラスが多くなる。
VSやRiderなどIDEによる管理が必要
慣れるまでは可読性が低い
キッズスターではクリーンアーキテクチャ開発をするうえでブラッシュアップをし、
今はCAFUという名前で開発しています。
レイヤー定義とかはスライドを見てください。
まとめ
依存の向きは外から内にすること
これはキッズスターでの事例です
境界を区別することが重要
#2. MagicOnion〜C#でゲームサーバを開発しよう〜
発表資料です
— とりすーぷ (@toRisouP) October 27, 2019
MagicOnion ~C#でゲームサーバを開発しよう~ by @toRisouP #netcore #magiconion https://t.co/CAFxCeovJm @SlideShareさんから#dotnetconfunity #dotnetconf
今回MagicOnionについてお話します。
スライドが脅威の180枚なので詳しくはそちらをどうぞ。
MagicOnionは何なのか
ネットワーク通信のフレームワーク。サーバーはC#で書けます。
定義した共有ファイルを介することすることで通信する。
通信レイヤを気にせずサーバーを呼び出せるのが特徴
MagicOnionの機能
実装パターンは2つ
Service
シンプルな単発通信
1リクエストに1レスポンス
SreamingHub
リアルタイム通信向け
コネクションを張ったまま維持し自由にメッセージを送信できる
Filter
通信の前後に処理を追加する機能
かなり用途があります。
環境構築
環境構築は大変
ライブラリの追加
クライアント(unity)に各ライブラリを手動で導入。
PlayerSettingも設定が必要。
(ついでにUniRxとUniTaskも便利なのでオススメ)
コードの共有
おすすめの方法はサーバー側のスクリプトにUnity/Assets以下を参照するよう記述。
プロジェクト構成も見直しましょう。Git管理する時は全部まとめてやる。
このやり方なら設定が楽で環境に依存しない。
ただし、リポジトリが1つなるので開発フローの整理が難しくなる。
これらのデメリットをなくすには、
サーバーとゲーム本体でリポジトリとして分けて接続部分は生成したunitypackageをインポートする。
コードジェネレート
MagicOnionではコードジェネレートが2回必要。
ジェネレータはそれぞれgithubから持ってきましょう。
ボタン一発でジェネレートできるエディター拡張もあるよ
環境構築まとめ
・環境構築が大変
・開発フローはよく考えよう
・リポジトリをどうわけるかなどはチーム内でよく話し合いましょう
実装例の紹介
詳しい手順はスライドを見てどうぞ
実装時の注意点 おぼえておくといいテクニック
gRPCのコネクション管理をちゃんとやりましょう
C#のgRPCはunmanaged、Disposeしないとすぐリークします、忘れないようにしましょう。
マネージャを自分で作って管理するとよい。
サーバー側でやっておくといい設定
・GCモードをServerに切り替えよう
・ThreadPoolのサイズを上げておこう。
・GenericHostを使おう
これはアプリケーション開発に便利なものをまとめたもの
MagicOnionもこの上で動かしましょう
実装の注意点のまとめ
・コネクション管理じゃ気を付けよう
・GenericHostを使おう。
デプロイ
サーバーで動かすならDockerビルド。
Kubernetesでコンテナ管理がよい。
MagicOnionのサーバー構成
2つの構成が選べます
事実上ステートフル一択
ステートフル構成
インメモリでデータを保持する実装。
リアルタイム通信に向いている、インメモリですむので外部ストレージも使わない。
Kubernetesと相性が悪い。
ステートレス構成
プロセス上に状態を持たない構成。プロセス同士がバックエンドで動く。
構成のまとめ
リアルタイム通信はステートフルがおすすめ。
ただしKubernetesがきびしい。
まとめ
・サーバサイドもC#でいい感じにつくれる
・クライアントとサーバをC#で統一できる
・開発フローの整備が課題
・サーバーサイドの開発知識はある程度必要
MagicOnionはいいぞ
#3. Riderはいいぞ!
.NET Conf in Tokyo 2019で発表した「Riderはいいぞ!」の発表資料です#dotnetconf#dotnetconfunity https://t.co/8NN6GZWjwd
— むろほし (@RyotaMurohoshi) October 27, 2019
Unityプログラマの皆様にRiderを使ってみたくなるような紹介セッションをします
デモタイム
Riderはコードを書く上でのわかりにくい改善ポイントを指摘してくれます。
こういう便利な機能がたくさんあります。
JetBrains
チェコにある会社です
様々な言語・プラットフォームのIDEを作っている会社です。Riderはその中の1つ。
Riderはクロスプラットフォームに対応しています。
さらにUnityのサポートが手厚い。
C#やUnityを始めた人に特におすすめ
教える側の人にもおすすめ
Riderの機能紹介
いい感じのコードに書き換えてくれるので、一部の人から赤ペン先生と呼ばれます。
それぞれ機能に名前がついています。
たくさんあるので詳しくはスライドを。
Code Inspections
・新しいC#に置き換えられるところを指摘してくれる
・エラーになっているところやなりそうなところの指摘
・到達しないコードや不必要なコードの指摘
・タイポの指摘
さらにレベルの概念があります。(エラー・警告・提案・ヒント)
・なんでよくないかも教えてくれる
・ソリューション全体や特定のディレクトリのみなど特定のスコープで探索もできる
・アセットやSDKの中のコードも分析対象になってしまうので、設定で無視するようにした方がいいです
Run Inspection by Name
特定のインスペクション項目のみ探す機能
コードの一括変換などに便利。
Qucik Fix
Code Inspectionsで指摘されたコードをサクッと修正できる機能
Code Vision
このコンポーネントどこで使われているかを見ることができる
どこのシーンのどこのプレハブで使われているか、インスペクターでどんな値が設定されているかも見れる。
Live Template
よくあるお決まりコードを作ってくれるが、同時に型や名前を同時に設定できる。
Unity用のテンプレートがたくさん用意されています。
さらに自分でテンプレートを作ることもできますし、共有できます。
Code Generation
よくあるコードやUnity標準のイベントファンクションズ(Startとか)も簡単に作れる
Perfomane Indicators
パフォーマンスチューニングをしてくれます。
明らかに非効率でやっちゃいけないところを指摘してくれる機能。
Update内でGetComponentを呼ぶなど
UnityEditorとの連携
RiderからUnityを制御でき。RiderからDebugLogを見ることができる。
BreakPoint内で変数を見ることができる
とりあえず覚えてほしいショートカット
Show Action List
option+enterまたはalt+enter
その文脈でできることを表示してくれる。
Find Action
Ctrl+Shift+A
Riderはできることがたくさんあるが、覚えれないことがある
それを検索できる
Serach Everywhere
Shift+Shift
コードもクラスもファイルもアクションなども全て検索できる
Code Inspectionsの提案理由はGitHubに一覧があるのでぜひ見てください。
Riderのチュートリアルもあります
Riderはいいぞ
#4. C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜
資料、動画は後日公開予定です。Burstコンパイラのお話をします。
コンパイラの話
書かれたC#は実行されるときは機械語になります。
その中間には何があるのか、普通はILがあります。
C#などはいったんILに変換され、AOTかJITで実行します。
現在は、IL2CPPの登場でLIからC++に変換します(WebGLで動かすために作られた)
今ではIL2CPPが基本になっている。
Burstコンパイラでもっと早くする
C#からILになるところは同じだが、そこからBurstコンパイラがIRに変換
そこからLLVMで機械語に変更します
LLVMとは
様々なプログラミング言語に対応可能なコンパイラ基盤。
昔は「Low Level Virtual Machine」という略称があったが今はない。
IR(Intermediate Representation 中間表現)
LLVMが扱う中間言語。
プログラミング言語、CPUアーキテクチャから独立している。
LLVMは機械語にする前にIRを最適化する。
なぜBurstは早いのか
LLVMの最適化が効くため
すごい最適化をしてくれる。人類が考えるあらゆる最適化が含まれている。
IRには最適化前と最適化後の2種類あります。
BurstはLLVMの読み込みやUnityとの連携をしてくれる。まさに人類の英知。
SIMD(シムド)
single instraction multiple data
ひとつの命令で複数の計算を行う仕組み。
SSE(Intel CPU) NEON(ARM UPC)など。
機械語の命令語のひとつ。
Burstの制約
1.C# Job Systemでしか使えない
2.クラスが使えない
ガベージコレクションを避けるためマネージドヒープを使う参照型は使えない
ただし代わりに構造体、NativeArrayが用意されています
3.例外処理ができない
try・catch・finallyが使えない、throwは使える(jobは止まる)
実演 波動方程式を使って波紋を出すデモ
NativeArrayはUnityエディタでの計測は信用できないので、ビルドして確認します。
結果8倍くらいはやくなる。
↓デモプロジェクト
注意点
Burstを動かす設定ですが、エディター実行時とビルド時で個別で設定する必要があります。
ビルドする時はProjectSettingから設定しましょう。
BurstInspectorも同様です。
ベクタライズは手動でやる必要があります。自動ではやってくれない。
まとめ
IL2CPPは汎用性が高かったが高速化ができなかった。
Burstは制約を設けることで高速化できた。
Burstは特にDOTSで威力を発揮します。
.NET Trackの資料
Unity Trackとは別室で行われていた.NET Trackの資料も載せておきます。
.NET Conf Tokyo 2019 のセッション資料です:「.NET の今と今後に思うこと (Tokyo Ver.)」 #dotnetconf #dotnet #visualstudio #azure https://t.co/1vuvwoGLEo
— Akira Inoue (井上 章) (@chack411) October 27, 2019
はてなブログに投稿しました #はてなブログ #dotnetconf
— かずき(Kazuki Ota) (@okazuki) October 27, 2019
.NET Core 3.0 + Windows 10 で WPF 開発 というタイトルで .NET Conf 2019 で登壇してきました - かずきのBlog@…https://t.co/HHwKJTEFA3
.NET Conf in Tokyo 2019 でのセッション資料です!世界最速 (たぶん) の Enum Utility「FastEnum」で使われているテクニックがいっぱい書かれています :)#dotnetconf#dotnetconfdotnethttps://t.co/Thh9gGNxgQ
— じんぐる (@xin9le) October 27, 2019
https://t.co/e0BGMiFi6O
— ++C++; // 管理人: 岩永 (@ufcpp) October 27, 2019
本日の登壇資料。
関連資料
CAFU
CAFU v3 完全に理解した / Updates for CAFU v3 - Speaker Deck
先日のRoppongi.unity #5にてUniFlowに関するLTがありました
SOLID原則についておすすめの資料
とりすーぷさん主催のMagicOnion勉強会のレポ
むろほしさんがJetBrains .NET Meetup Tokyoにてされた講演資料
Burstコンパイラではありませんが関係のあるDOTSの資料
他の方の感想ブログとか
いろいろ理解が足りていないため間違っている箇所がありましたら、コメントにお願いします。