【Unity道場京都スペシャル4】Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現

2.3K Views

January 27, 20

スライド概要

2020/1/25に開催されたUnity道場京都スペシャル4の講演スライドです。
講師:河合 宜文(株式会社Cysharp)
Unityのイベント資料はこちらから:https://www.slideshare.net/UnityTechnologiesJapan/clipboards

profile-image

リアルタイム3Dコンテンツを制作・運用するための世界的にリードするプラットフォームである「Unity」の日本国内における販売、サポート、コミュニティ活動、研究開発、教育支援を行っています。ゲーム開発者からアーティスト、建築家、自動車デザイナー、映画製作者など、さまざまなクリエイターがUnityを使い想像力を発揮しています。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
2.

河合 宜文 / Kawai Yoshifumi / @neuecc Cysharp, Inc. Cygames C#大統一理論 C#

3.

https://github.com/Cysharp MagicOnion SlnMerge MasterMemory RuntimeUnitTestToolkit UniTask RandomFixtureKit

4.

https://github.com/Cysharp ConsoleAppFramework ValueTaskSupplement LitJWT Ulid Difference

5.

https://github.com/neuecc UniRx MessagePack-CSharp ZeroFormatter Utf8Json LINQ to GameObject SerializableDictionary CloudStructures Open on GitHub

7.

Unified Realtime/API Engine https://github.com/Cysharp/MagicOnion 特徴

8.

全てのロジックをC#サーバー上で実行 AI・演算・結果処理など全てサーバー側で処理

9.

Realtime Network

10.

P2P Realtime Server Unity Native App Browser Microser vices API Server

11.

P2P Realtime Server Unity Native App Browser Microser vices API Server

12.

P2P Dedicated Server

13.

P2P Dedicated Server

14.

Realtime Server Unity Native App Browser Microser vices API Server

15.

⚫ ⚫ ⚫ ⚫ ⚫ ⚫ ⚫ Unity Connected Games Photon Engine Monobit Engine DIY - WebSocket + Server App DIY - WebSocket + mBaaS DIY - TCP(UDP) + Server App DIY - TCP(UDP) + Unity Headless

16.

Unity Connected Games

17.

Photon Engine Monobit Engine

18.

WebSocket + ServerApp WebSocket(TCP/UDP) + mBaaS(mobile backend as a Service)

19.

TCP(UDP) + ServerApp TCP(UDP) + Unity HeadlessApp

20.

TCP(UDP) + ServerApp TCP(UDP) + Unity HeadlessApp

21.

About MagicOnion

22.
[beta]
C#の型が通信定義となる単方向/双方向RPC
// 自然な書き味で、タイプセーフにRPC(Remote Procedure Call)を実現
// C#のasync/await構文により、非同期通信も自然に見える
var client = MagicOnionClient.Create<ITestService>(channel);
var result = await client.Sum(100, 200);

public class TestService : ITestService
{
public async UnaryResult<int> Sum(int x, int y)
{
return x + y;
}
}

23.
[beta]
クライアントもサーバーも自
然に繋がっているように見え
る(デバッガもサーバー/クラ
イアント共有でステップ実行
で繋がって動いていく)
Call)を実現

C#の型が通信定義となる単方向/双方向RPC
// 自然な書き味で、タイプセーフにRPC(Remote Procedure
// C#のasync/await構文により、非同期通信も自然に見える
var client = MagicOnionClient.Create<ITestService>(channel);
var result = await client.Sum(100, 200);

public class TestService : ITestService
{
public async UnaryResult<int> Sum(int x, int y)
{
return x + y;
}
}

24.
[beta]
リアルタイム通信のための双方向の型付きRPC

public interface IGamingHub : IStreamingHub<IGamingHub, IGamingHub
{
Task<Player[]> JoinAsync(string roomName, string userName, Vec
Task LeaveAsync();
Task MoveAsync(Vector3 position, Quaternion rotation);
}
public interface IGamingHubReceiver
{
void OnJoin(Player player);
void OnLeave(Player player);
void OnMove(Player player);
}

26.
[beta]
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Call, typeof(AsyncDuplexStreamingCall<byte[], byte[]>).GetProperty("RequestStream").GetMethod);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, serializerOptionsField);
il.Emit(OpCodes.Newobj, (typeof(MarshallingClientStreamWriter<>).MakeGenericType(def.RequestType).GetConstructors().Singl
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Call, typeof(AsyncDuplexStreamingCall<byte[], byte[]>).GetProperty("ResponseStream").GetMethod);
il.Emit(OpCodes.Ldarg_0);
MethodType t;
il.Emit(OpCodes.Ldfld, serializerOptionsField);
string requestType;
il.Emit(OpCodes.Newobj, (typeof(MarshallingAsyncStreamReader<>).MakeGenericType(def.ResponseType).GetConstructors().Singl
string responseType;
il.Emit(OpCodes.Ldarg_0);
ITypeSymbol unwrappedOriginalResponseType;
il.Emit(OpCodes.Ldfld, serializerOptionsField);
ExtractRequestResponseType(y, out t, out requestType, ou
resultType2 = typeof(DuplexStreamingResult<,>).MakeGenericType(def.RequestType,
var id =def.ResponseType);
FNV1A32.GetHashCode(y.Name);
il.Emit(OpCodes.Newobj, resultType2.GetConstructors()[0]);

return new MethodDefinition
{
Name = y.Name,
MethodType = t,
RequestType = requestType,
ResponseType = responseType,
UnwrappedOriginalResposneTypeSymbol = unwrappedOrigi
OriginalResponseTypeSymbol = y.ReturnType,
IsIfDebug = y.GetAttributes().FindAttributeShortName
HubId = id,
Parameters = y.Parameters.Select(p =>
{

27.

C#で自然にサーバーとクライアントを繋げる 機能として提供するものはシンプルなRPCのみ あとはアプリケーションの作り込みで何でも作れる Unityにも依存しないことであらゆる使い方ができる(サーバーtoサーバーなど) 一つのシンプルなやり方で応用が効く(土管にもなるし土管以外もOK) サーバープログラムを透明にしない どちらにも平等に配置できることを意識したフレームワーク サーバーもクライアントもどちらも大事 適切な場所に適切なコードを書くことで、サーバー/クライアント全体を通し たアーキテクチャの最適化を支援する

28.

エコシステムには全部乗る 未来で償却する

29.

エコシステムには全部乗る 未来で償却する

30.

All in Oneではない RPCしかない

31.

API Services

32.

Realtime Server Unity Native App Browser Microser vices API Server

33.

Realtime Server Unity Native App Browser Microser vices API Server

34.

PROS CONS

35.

中間言語からコード生成する サーバーコード (PHP/Ruby/Go/C#/etc...) IDL(JSON/XML/proto/etc...) クライアントコード (C#/Swift/JavaScript/etc...)

36.

PROS CONS

37.

protoはC#/* 任意の言語 */ではない

38.

C# as a Schema C#に固定することで 通信定義そのものをC#で表現する

39.

言語の違うREST Response型を別々 に書く APIクライアント を手書きする (ザ・マイクロ サービスみたいな 構成) 中間IDLを書く そこからクライア ント・レスポンス 型自動生成 (←を嫌う時によ くある構成、一番 メジャー) サービスを普通に 書く、そこからク ライアントを自動 生成、リクエス ト・レスポンス型 はC#のDLLとして 共有 サービスを普通に 書く、クライアン トはそのプロジェ クト参照から実行 時動的生成

40.

認証、課金、クエスト、ミッション、etc...

41.

https://logmi.jp/tech/articles/322333

42.

適切なコードを適切なところに書く 作り込みを現実のものにする

43.

適切なコードを適切なところに書く 作り込みを現実のものにする

44.

MagicOnion is Unified Realtime/API Engine

45.

Realtime Server Unity Native App Browser Microser vices API Server

46.

サーバーとクライアントの距離が限りなく近い

47.
[beta]
ConsoleAppFramework
https://github.com/Cysharp/ConsoleAppFramework
引数の自動割当
複数コマンドのルーティング
コンフィグ処理
ロギング処理
ライフサイクル管理(Daemon)

class Program : ConsoleAppBas
{
static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder()
.RunConsoleAppFrameworkAsync<Program>(args);
}
public void Run(string name, int repeat = 3)
{
for (int i = 0; i < repeat; i++)
{
Console.WriteLine($"Hello from {name}");
}
}

などCLIの面倒ごとに対応
}

48.

API Service Realtime Unity

49.

API Service Realtime Unity

50.

Conclusion

51.

時代の変わり目を超える リアルタイム通信がほぼ必須だったり、5Gが迫っていたり 旧来のフレームワークから変わっていくタイミング 一歩先の理想形へ クライアントとサーバーを、APIとリアルタイムを 全てをC#で統合するという夢想を具現化するのがMagicOnion ただの旧来のXXの置き換えなどではなく、 誰も見たことのない究極的な理想の形に近づけていく 銀の弾丸はないので、相応の困難は発生するかもしれないけれど ぜひ一緒に乗り越えていきましょう!→お、コンタクトフォームが https://cysharp.co.jp/contact/