Upload
yoshifumi-kawai
View
17.320
Download
1
Embed Size (px)
Citation preview
Work
C#
Unity
Private
http://neue.cc/
@neuecc
https://github.com/neuecc/UniRx
About Grani
モバイル向けゲーム開発企業
http://grani.jp/
2012年設立
代表作として「神獄のヴァルハラゲート」
GREE Platform Awardにて殿堂入り最優秀賞
他、カプコンとの共同開発による「モンスターハンター ロア オブ カード」
iOS/Android向けに次期タイトル「黒騎士と白の魔王」鋭意開発中
using
using
Unity + Realtime
ゲームのメイン部分
チャット・通知系システム
Socket.io
ASP.NET SignalR
Unity Multiplayer(UNET)
モノビットエンジン
サーバー側の分散手法が弱い
Unity向けの標準クライアントがない
プロトコルが重い
固定のシリアライゼーションフォーマット
C#であること
サーバー側にロジックが書けること
大規模MMORPGなどへの発展性があること
実績がある
Photon Family
Realtime/(Turnbased)/Chat/Voice/Server...
サーバーに実装を入れたい
PUN(Photon Unity Network)
PUNを使わない100の理由
Getting Started
Photon Server
実態はただのクラスライブラリ
実行フロー
public class Startup : ApplicationBase{
// サーバーに接続が入った時のコネクション生成ハンドリングprotected override PeerBase CreatePeer(InitRequest initRequest){
if (/* クライアントからのリクエストなら */){
return new MyClientPeer(initRequest);}else // サーバーからのリクエストなら{
return new InboundS2SPeer(initRequest);}
}
protected override void Setup(){
// 起動時の処理// マスターサーバーに繋げるならOutboundS2SPeerを作ったりvar outboundPeer = new OutboundS2SPeer();outboundPeer.ConnectTcp();
}
protected override void TearDown(){
// 終了時の処理}
}
public class MyClientPeer : ClientPeer{
public MyClientPeer(InitRequest initRequest): base(initRequest)
{
}
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters{
// byte: operationRequest.OperationCode// Dictionary<byte, object>: operationRequest.Parameters
// クライアントにレスポンスを送信this.SendOperationResponse(new OperationResponse(), sendParameters);
}
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail){}
}
// 1. Unity側からサーバーへ送信var peer = new ClientSidePeer(new MyListener());peer.OpCustom(opCode: 10, parameter: new Dictionary<byte, object>());
// 2. サーバー側が受信するprotected override void OnOperationRequest(OperationRequest operationRequest){
// opCodeで分岐switch (operationRequest.OperationCode){
case 10:// データはDictionaryに詰まってるのでそれを取り出す(<byte, object>)var parameter = operationRequest.Parameters;
/* それを使って何か処理する */
// 3. 処理終わったということでクライアントに結果を送るthis.SendOperationResponse(new OperationResponse(operationCode: 5));break;
default:break;
}}
// Unityクライアント側public class MyListener : IPhotonPeerListener{
// 4. クライアント受信public void OnOperationResponse(OperationResponse operationResponse){
// 返ってきたレスポンスswitch (operationResponse.OperationCode){
case 5:// なんかするbreak;
}}
}
// 3. サーバー側:処理終わったということでクライアントに結果を送るthis.SendOperationResponse(new OperationResponse(operationCode: 5), sendParameters);
// opCodeで分岐switch (operationRequest.OperationCode){
case 0:break;
case 1:break;
case 2:break;
case 3:break;
case 4:break;
case 5:break;
case 6:break;
case 7:break;
case 8:break;
case 9:break
case 10:break;
// opCodeで分岐switch (operationRequest.OperationCode){
case 0:break;
case 1:break;
case 2:break;
case 3:break;
case 4:break;
case 5:break;
// opCodeで分岐switch (operationRequest.OperationCode){
case 0:break;
case 1:break;
case 2:break;
case 3:break;
case 4:
Intro to PhotonWire
byte, Dictionaryを送りswitch、送り返してswitch
クライアントの送信と受信がバラバラ
Typed Asynchronous RPC Layerhttps://github.com/neuecc/PhotonWire
Demo...
専用のWindowsクライアント
Server to Server
なにもないことはいいこと
Into the Photon Server
非常にプリミティブ
複雑な機能は全てロジックに寄る
接続
4種類ある送信メソッド
当然受信側も4種類
SendEvent/OnEvent
SendMessage/OnMessage
SendOperationRequest/OnOperationRequest
SendOperationResponse/OnOperationResponse
SendEvent/OnEvent
SendMessage/OnMessage
SendOperationRequest/OnOperationRequest
SendOperationResponse/OnOperationResponse
シリアル化
サポート型は少なめ
Next PhotonWire
デシリアライズ速度
シリアライザの置き換え
(De)serialize is slow...
ScriptableObject > JsonUtility > (越えられない壁) > MsgPack > XxxJSON
デシリアライズしない新フォーマット
C#, Unityにフィットさせる
近日公開予定
Configuration of Photon
<?xml version="1.0" encoding="shift-jis"?><Configuration>
<DevLocal><!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --><Runtime
Assembly="PhotonHostRuntime, Culture=neutral"Type="PhotonHostRuntime.PhotonDomainManager"CLRVersion="v4.0"UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --><TCPListeners>
<TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /></TCPListeners>
<Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"><Application
Name="MyApp.GameServer"BaseDirectory="MyApp"Assembly="MyApp"Type="MyApp.GameServerStartup"EnableShadowCopy="true"EnableAutoRestart="true"ForceAutoRestart="true"ApplicationRootDirectory="PhotonLibs">
</Application></Applications>
</DevLocal></Configuration>
<?xml version="1.0" encoding="shift-jis"?><Configuration>
<DevLocal><!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --><Runtime
Assembly="PhotonHostRuntime, Culture=neutral"Type="PhotonHostRuntime.PhotonDomainManager"CLRVersion="v4.0"UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --><TCPListeners>
<TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /></TCPListeners>
<Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"><Application
Name="MyApp.GameServer"BaseDirectory="MyApp"Assembly="MyApp"Type="MyApp.GameServerStartup"EnableShadowCopy="true"EnableAutoRestart="true"ForceAutoRestart="true"ApplicationRootDirectory="PhotonLibs">
</Application></Applications>
</DevLocal></Configuration>
<?xml version="1.0" encoding="shift-jis"?><Configuration>
<DevLocal><!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --><Runtime
Assembly="PhotonHostRuntime, Culture=neutral"Type="PhotonHostRuntime.PhotonDomainManager"CLRVersion="v4.0"UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --><TCPListeners>
<TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /></TCPListeners>
<Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"><Application
Name="MyApp.GameServer"BaseDirectory="MyApp"Assembly="MyApp"Type="MyApp.GameServerStartup"EnableShadowCopy="true"EnableAutoRestart="true"ForceAutoRestart="true"ApplicationRootDirectory="PhotonLibs">
</Application></Applications>
</DevLocal></Configuration>
<?xml version="1.0" encoding="shift-jis"?><Configuration>
<DevLocal><!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --><Runtime
Assembly="PhotonHostRuntime, Culture=neutral"Type="PhotonHostRuntime.PhotonDomainManager"CLRVersion="v4.0"UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --><TCPListeners>
<TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /></TCPListeners>
<Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"><Application
Name="MyApp.GameServer"BaseDirectory="MyApp"Assembly="MyApp"Type="MyApp.GameServerStartup"EnableShadowCopy="true"EnableAutoRestart="true"ForceAutoRestart="true"ApplicationRootDirectory="PhotonLibs">
</Application></Applications>
</DevLocal></Configuration>
<?xml version="1.0" encoding="shift-jis"?><Configuration>
<DevLocal><!-- CLRVersionを使ってる.NETのバージョンに合わせる。.NET 4.5~6はCLR v4.0 --><Runtime
Assembly="PhotonHostRuntime, Culture=neutral"Type="PhotonHostRuntime.PhotonDomainManager"CLRVersion="v4.0"UnhandledExceptionPolicy="Ignore">
</Runtime>
<!-- InactivityTimeout(ms)はローカルでは0にする(デバッガで止めてる最中にも強制切断が辛いので) --><TCPListeners>
<TCPListener IPAddress="127.0.0.1" Port="4530" ListenBacklog="1000" InactivityTimeout="0" /></TCPListeners>
<Applications Default="MyApp.GameServer" PassUnknownAppsToDefaultApp="true"><Application
Name="MyApp.GameServer"BaseDirectory="MyApp"Assembly="MyApp"Type="MyApp.GameServerStartup"EnableShadowCopy="true"EnableAutoRestart="true"ForceAutoRestart="true"ApplicationRootDirectory="PhotonLibs">
</Application></Applications>
</DevLocal></Configuration>
Conclusion
真価は出してみないとわからん
Photon Serverは良い
PhotonWireは良い
Hiringhttp://recruit.grani.jp/