Contenu connexe Similaire à Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー Similaire à Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー (20) Plus de Yoshifumi Kawai (20) Unity C#と.NET Core(MagicOnion) C# そしてKotlinによるハーモニー2. 講演者プロフィール
• 河合 宜文 / Kawai Yoshifumi / @neuecc
• Cysharp, Inc. – CEO/CTO
• 株式会社Cygamesの子会社としてC#関連の研究開発やコンサ
ルティングを行う
• メインミッションはC#大統一理論(サーバー/クライアント共にC#で
実装する)の推進
• 株式会社アプリボットの新規タイトル(タイトル未発表)におけ
るMagicOnionの導入と周辺の基盤開発を担当
6. MagicOnion
• Unified Realtime/API Engine for .NET Core and Unity
• https://github.com/Cysharp/MagicOnion/
• Cysharp開発のC#によるOSSのネットワークエンジン
• リアルタイム系もAPI系も両方OK
• HTTP/2 gRPCの上に構築され、高性能とスタンダードを両立
• .NET CoreによるLinuxホスティングと完全なコンテナ対応
• 現在GitHub Starが1000以上と、国内外でも注目度上昇中
• パフォーマンスとC#としての使い勝手にこだわって開発
• C#のエキスパートが最初からUnity C#も前提に組み立てているた
め、C#のためのエンジンとして高い品質を誇る
7. public class TestService : ITestService
{
// パブリックメソッドがそのままgRPC定義
public async UnaryResult<int> Sum(int x, int y)
{
// async/awaitにも自然に対応
// マジカル技術によりasync Task<T>じゃなくてもawait可能
await Task.Yield();
return x + y;
}
}
// 普通のgRPCの接続を作る(MagicOnion用の特別なことはない)
var channel = new Channel("127.0.0.1:12345");
// 自然な書き味で、タイプセーフにRPC通信を実現
// C#のasync/await構文により、非同期通信も自然に見える
var client = MagicOnionClient.Create<ITestService>(channel);
var result = await client.Sum(100, 200);
クライアントもサーバーも自
然に繋がっているように見え
る(デバッガもサーバー/クラ
イアント共有でステップ実行
で繋がって動いていく)
9. Why not (plain) gRPC
• protoはC#ではない!!!
• 故に言語の持つ
• 全ての型(Primitive, Nullable, Dictionaryなど)が使えない
• 属性(Attribute, Annotation)付与ができない
• リクエスト毎に必ず一つの型が必要になる
• 故にIDE(Visual Studio, Rider, etc...)の持つ
• シンタックスハイライトが効かない
• コードレンズなどのコード追跡機能が効かない
• リファクタリング支援(名前一括変更など)が効かない
• サーバー/クライアント大統一ならクライアント/サーバー超えて変更
される!
10. C#がIDLなら
C# as a Schema
クライアント/サーバーの実装言語を
共にC#に固定することで、
通信スキーマそのものをC#で表現する
プロジェクト参照で済むので
IDLのバージョン管理が不要というのも運用上メリット
21. 案D. C# to Kotlinでコード共有(採用)
• C#を正としてUnity側中心にロジックを書いてしまい、Kotlin
側はC#からのコードジェネレートで生成する
• MicroBatchFramework
• https://github.com/Cysharp/MicroBatchFramework
• C#(.NET Core)でCLIツール作るのに便利なフレームワーク
• Roslyn(Microsoft.CodeAnalysis.CSharp)
• C#によるC#コンパイラ
• C#のAbstract Syntax Treeが取れる
22. class Program : BatchBase
{
static async Task Main(string[] args)
{
await BatchHost.CreateDefaultBuilder().RunBatchEngineAsync<Program>(args);
}
public void Generate(
[Option("i", "入力するフォルダ")]string inputDirectory,
[Option("o", "出力するフォルダ")]string outputDirectory)
{
foreach (var inputFilePath in Directory.GetFiles(inputDirectory,
"*.cs", SearchOption.AllDirectories))
{
var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(inputFilePath));
var parseInfo = Parse(tree);
foreach (var item in parseInfo)
{
var template = new KotlinTemplate
{
ClassInfo = item
};
var code = template.TransformText();
var outPath = Path.Combine(outputDirectory, item.ClassName) + ".kt";
File.WriteAllText(outPath, code, Encoding.UTF8); }
CSharpSyntaxTree.ParseTextで.cs
ファイルからSyntaxTreeを取得
テンプレートエンジン(T4)を使って
Kotlinコードを生成
MicroBatchFrameworkによる
CLI定義と実装
ASTを元にテンプレートに当ては
める情報を生成(自前実装)
26. vs Unity .csproj
• UnityはUnityの管理下のソースコードのみ参照可能
• サーバーのcsprojは柔軟に記述できる
• よって共有するコードの実体をUnityのほうに置いて、サー
バー側ではコードリンクで参照する
<ItemGroup>
<Compile Include="..¥Unity¥Assets¥Scripts¥Shared¥**¥*.cs" />
</ItemGroup>
シンボリックリンクとか、ビルドしてマ
ネージドDLLを配置とかやるとトラブルの
元なので、シンプルな手段が一番
シェアするディレクトリはasmdef
で切っておくとより良い
27. Unity Shimsの実装
• Unity依存コードの除去
• 理想的には完全除去が望ましいが、特に開発中でUnity側主導でコード
ができあがっている場合、残ってしまっていることが多い
• ダミーの型を用意して回避するのが手っ取り早くは楽
namespace UnityEngine
{
public class ScriptableObject {}
public class MonoBehaviour {}
public sealed class SerializeFieldAttribute : Attribute
{
}
// etc...
}
意外と問題なく動いたり動かなかったり。
とりあえずコンパイル通す→動かして問題出た
とこを何とかする、で工数的にそんな多くかか
らず何とかなる、ことも少なくないかな、と。
36. MagicOnion is...
• High Performance
• gRPC(HTTP/2) + MessagePack-CSharp
• Modern Architecture
• .NET Core, Container, OpenTelemetry
• C# Friendly
• C# as a Schema
• Unity Friendly
• Runtime/CodeGen(for IL2CPP)
37. 未来を構築する
• 新しい時代の新しいフレームワーク
• 今やゲームにおいてリアルタイム通信はほぼ必須
• 5Gも迫っていてフレームワークも変化しなければいけないタイミング
• ならばこそ、より大きな未来を描いていきたい
• 完全統合形フレームワークという一つの理想
• クライアントとサーバーを
• APIとリアルタイムを
• 全てをC#で統合するという夢想を具現化するのがMagicOnion
• 理想を理想のままにせず、現実の結果に残すためにCysharpはOSSに
よる公開から、開発サポートまで様々なことをしていきます!