やらなイカ?

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

.NET Conf in Tokyo 2019に行ってきました #dotnetconf #dotnetconfunity

日本マイクロソフトさんで行われた、.NET Conf in Tokyo 2019 に行ってきました。

vsuc.connpass.com

午後は2部屋に分かれたうちの Room B(Unityトラック)にずっといました。 Room C+D(.NETトラック)が気になる方はハッシュタグ #dotnetconfdotnet を参照。

以下、スライドは拾えたものだけ。Unityトラック分は近日中にUnity Learning Materialsで公開されるはずです。

What’s New in .NET Core 3.0 and Visual Studio 2019 for .NET developers

MicrosoftのSteve Carrollさん

サテライトの音声よくなかったこともあって*1ろくにメモできていません…

デモアプリ等はここに。

https://github.com/dotnet-presentations/dotnetconf2019/tree/master/Technical/keynotegithub.com

Clean Architecture for Unity

www.slideshare.net

  • @monry さん
  • Visual Studio Users Community Japan #1における@nuits_jpさんの『世界一わかりやすいClean Architecture』とかぶった
  • Clean Architecture(以下CA)とはなにか → そんなものはない
    • ざっくりとした指針は示されている
  • CAの図は、あくまで一例。押さえるべきポイントを押さえれば自ずとCAになる
  • SOLID原則とDI
    • SOLIDの元論文は2000年、Robert C. Martin氏
      • CA本の著者
      • その時点ではSOLIDという略称ではない
    • DI
      • DIPを実現するパターン
      • Zenject
        • Unityにおいては、MonoBehaviourに対するinjectが難しい
        • Installerで実体の作り方/探し方を定義
  • UnityにおけるCA
    • ざっくりした方針は2つだけ
      • 依存の向きは外から内のみ
      • 制御の流れは依存と切り離して考える
    • pros: 疎結合、テスタビリティ、慣れると可読性が高い
    • cons: interface/class多い(3-4倍+)、要IDEVSCodeでは厳しそうなレベル)、慣れるまで可読性低い
    • CAFU (Clean Architecture for Unity) を作って使っている(キッズスター社)
    • レイヤ定義
      • Application:
        • CAの文脈から外れる要素はここに置く。他から結構依存される
        • ValueObject
          • マスタデータ用の型、enum
          • 状態管理、transaction
        • Installer
          • ZenjectのInstaller
        • Signal
          • 抽象を用いないで制御を授受するための型。struct
          • UniRx.MessageBroker, Zenject.SignalBusとか
      • Domain: Entity, Use Case
        • Entity: 計算。Use Caseとのみ対話する
        • Use Case: Entityと対話。RepositoryやPresenterをつなぐ。Use Caseのみで完結可能な処理もある(Entity使わない)
      • Data: Repository, Datastore
        • Repository: Datastoreと対話。窓口。CRUDなインタフェース
        • DataStore: 実際に管理。メモリ、DB
      • Presentation: Presenter, View
        • Presenter: ユーザ対話の窓口、Viewと対話
        • View: ユーザとの対話。要するにUnity
    • 処理の起点はUse Caseに担わせるとよさげ
    • Zenject.IInitializable.Initialize()を実装させる
    • 状態をDataレイヤに取り扱わせる(Entityだとめんどくさかった)
    • 特にwriteはDataで行なう
    • Viewをいかに一般化するか。UniFlowを作っている

参考

booth.pm

MagicOnion〜C#でゲームサーバを開発しよう〜

www.slideshare.net

  • @toRisouP さん
  • サーバ: .NET Core, クライアント: Unity or .Net Core という構成
  • gRPCだが、データフォーマットはMessagePack for C#、protoc不要
  • 定義(C#コード)をクライアントとサーバのプロジェクトで共有
  • gRPCコネクションを張って、あとはasync/awaitでメソッドを呼ぶだけ
  • 実装できるAPI: Service, StreamingHub
    • StreamingHub: gRPCのBidirectional Streaming RPC
  • Filter: 通信の前後に処理を追加できる
    • フィルタメソッド定義して、フィルタ有効にしたいメソッドにAttributeつければok
    • 認証とかログとかエラー処理とか
  • Swagger, Telemetry対応
  • 環境構築はむつかしい
  • StreamingHub
    • クラサバ両方で状態を管理する必要があるので複雑になりがち
    • Receiver: サーバ → クライアント
    • Hub: クライアント → サーバ
    • MessagePackObjectを定義
      • サーバ側にMessagePack.UnityShimsを入れると、Vector3とか使えてべんり
    • Group: Hubを束ねる
    • Broadcast: いろいろある
  • 実装時の注意
    • クライアント
      • gRPCのコネクション管理ちゃんとしないとフリーズしたりする。Unmanaged
    • サーバ
      • .NETのServer GCを使うのおすすめ
      • ThreadPoolのサイズを上げる。デフォルト25なので
      • Generic Hostを使う
  • デプロイ
    • Docker, CircleCI, Kubernetesでコンテナ管理がよさげ
    • MagicOnionのサーバ構成
      • ステートフル: インメモリでデータを保持する、Groupはインスタンス縛り、リアルタイムに向く
        • Agonesに期待
      • ステートレス: Load Balanserに繋げばやってくれる。オートスケーリングできる
        • バックエンドにRedisが必要

Riderはいいぞ!

speakerdeck.com

  • @RyotaMurohoshi さん
  • Code Inspection
  • solution-wide analysis
    • preferencesで有効化。デフォルトはerrorのみ?
    • ディレクトリを指定できる
  • Quick Fix
    • 書いているソースだけでなくプロジェクト全体とか特定範囲とかもできる
  • Code Vision
    • Find Unity Usage
  • Live Template
    • preferencesで設定
    • 自分でも登録できる
  • File Template
  • Code Generation
    • MonoBehaviourのメソッドを作ってくれる: Unity Event Functions
  • Performance Indicators: Update()から呼ばれてるメソッドで非効率なコードを書くと怒られる
  • Unity連携、デバッガ*3
  • おすすめショートカット
    • alt + enter : Quick Action*4
    • shift + command + A : Find Action
    • shift + shift : Search
  • チュートリアルがある*5

参考

[.NET/Unity開発者向け] JetBrains .NET Meetup Tokyo #JBRiderTokyo - JetBrains | Doorkeeper におけるJetBrains社のKirill Skryganさんのセッション動画

www.youtube.com www.youtube.com

書籍

C#×LLVM=アセンブラ!? 〜詳説・Burstコンパイラー〜

learning.unity3d.jp

  • Unity 安原さん、名雪さん
  • 以前: C# → IL → Mono(AOT/JIT) → 機械語
  • IL2CPP*6: C# → IL → C++機械語
  • Burst: C# → IL →(Burst)→ IR*7 →(LLVM)→ 機械語
  • なぜBurstが速いのか
    • LLVMがIRをすごい最適化する
      • IL2CPPは互換性重視、インライン展開されにくいなど
    • SIMD*8を使う
      • SSE (Intel), NEON (ARM)
      • プラットフォームによって対応情報は違う。SSE2, SSE4とか
    • メモリエイリアス
      • memcpy()もベクタライズ
      • srcとdstの範囲が重なっている可能性 → 結果が変わってしまう → ビルドエラーが出てくれる
  • 制約
    • C# Job Systemのみ
    • クラスなど参照型が使えない → struct, NativeArray, NativeString
    • 例外処理できない。throwは使える
  • 実演
    • DOTSのプロファイリングはPlayerビルドしてプロファイラつないで見る
    • 25ms → 3msに高速化
  • メニューの Jobs > Burst : エディタ実行するとき設定
    • Enable Compilation
    • Safety Checks
  • Project Settings > Burst AOT Settings : Playerビルドするときはこちらの設定が使われるので注意
  • メニューの Jobs > Burst > Open Inspector...
    • "Refresh Disassembly"をクリックすると表示される
    • このウィンドウ用にコンパイルされるので、"Safty Checks"トグルとかもここだけに影響する(上記2つの設定とはまた別)
    • "Enhanced Disassembly"をonにすると、コメントとしてC#コードが出てくれるはず
  • float4を使うコードに書き換えるなどしないと勝手にベクタライズはされにくい。やっても早くなるとは限らない。LLVMだけでも十分速くなるはず
  • 機種間deterministic
    • 単精度のadd, sub, mul, div, sqrtは保証されている。すごい
  • Unity.Burst.Intrinsics
    • public static m128 load_ps_128(void* ptr) とか

所感

いずれのセッションも濃い話でたいへん勉強になりました。 はじめ、Unity側は(中途半端には)知っている話もあるし.NET側に行こうかとも考えたのですが、Unity側で正解でした。 Burstコンパイラ完全に理解した。

お土産にいただいたピンバッジ。かわいい。C#ステッカーもかわいい。

f:id:nowsprinting:20191027202108j:plain:w300

*1:最初C+Dに入ったのですがどうせ午後Bだからと移動して、そのまま居着いてしまった

*2:作者の@neueccさんのお言葉: https://twitter.com/neuecc/status/1188329065318498305, https://twitter.com/neuecc/status/1188330470515208193

*3:ちなみにEdit Mode testsもデバッガで実行できます。べんり!

*4:ちなみにテストメソッドにフォーカスした状態ではRunとDebugが出てきます。べんり!

*5:Riderのスプラッシュ画面右下のGet Help > Tutorials...

*6:WebGLで動かすためにハックウィークで作ってみたのが発端とか。後になって速度面とかiOSの64bit対応問題でメインストリームになったと

*7:Intermediate Representation: 中間表現

*8:Single Instruction Multiple Data: しむど