54
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6 <!DOCTYPE html>
|
|
7 <html>
|
|
8 <head>
|
|
9 <meta http-equiv="content-type" content="text/html;charset=utf-8">
|
|
10 <title>継続を使用する並列分散フレームワークのUnity実装</title>
|
|
11
|
|
12 <meta name="generator" content="Slide Show (S9) v4.1.0 on Ruby 2.6.3 (2019-04-16) [universal.x86_64-darwin19]">
|
|
13 <meta name="author" content="Ryo Yasuda, Shinji Kono" >
|
|
14
|
|
15 <!-- style sheet links -->
|
|
16 <link rel="stylesheet" href="s6/themes/projection.css" media="screen,projection">
|
|
17 <link rel="stylesheet" href="s6/themes/screen.css" media="screen">
|
|
18 <link rel="stylesheet" href="s6/themes/print.css" media="print">
|
|
19 <link rel="stylesheet" href="s6/themes/blank.css" media="screen,projection">
|
|
20
|
|
21 <!-- JS -->
|
|
22 <script src="s6/js/jquery-1.11.3.min.js"></script>
|
|
23 <script src="s6/js/jquery.slideshow.js"></script>
|
|
24 <script src="s6/js/jquery.slideshow.counter.js"></script>
|
|
25 <script src="s6/js/jquery.slideshow.controls.js"></script>
|
|
26 <script src="s6/js/jquery.slideshow.footer.js"></script>
|
|
27 <script src="s6/js/jquery.slideshow.autoplay.js"></script>
|
|
28
|
|
29 <!-- prettify -->
|
|
30 <link rel="stylesheet" href="scripts/prettify.css">
|
|
31 <script src="scripts/prettify.js"></script>
|
|
32
|
|
33 <script>
|
|
34 $(document).ready( function() {
|
|
35 Slideshow.init();
|
|
36
|
|
37 $('code').each(function(_, el) {
|
|
38 if (!el.classList.contains('noprettyprint')) {
|
|
39 el.classList.add('prettyprint');
|
|
40 }
|
|
41 });
|
|
42 prettyPrint();
|
|
43 } );
|
|
44
|
|
45 </script>
|
|
46
|
|
47 <!-- Better Browser Banner for Microsoft Internet Explorer (IE) -->
|
|
48 <!--[if IE]>
|
|
49 <script src="s6/js/jquery.microsoft.js"></script>
|
|
50 <![endif]-->
|
|
51
|
|
52
|
|
53
|
|
54 </head>
|
|
55 <body>
|
|
56
|
|
57 <div class="layout">
|
|
58 <div id="header"></div>
|
|
59 <div id="footer">
|
|
60 <div align="right">
|
|
61 <img src="s6/images/logo.svg" width="200px">
|
|
62 </div>
|
|
63 </div>
|
|
64 </div>
|
|
65
|
|
66 <div class="presentation">
|
|
67
|
|
68 <div class='slide cover'>
|
|
69 <table width="90%" height="90%" border="0" align="center">
|
|
70 <tr>
|
|
71 <td>
|
|
72 <div align="center">
|
|
73 <h1><font color="#808db5">継続を使用する並列分散フレームワークのUnity実装</font></h1>
|
|
74 </div>
|
|
75 </td>
|
|
76 </tr>
|
|
77 <tr>
|
|
78 <td>
|
|
79 <div align="left">
|
|
80 Ryo Yasuda, Shinji Kono
|
|
81 並列信頼研
|
|
82 <hr style="color:#ffcc00;background-color:#ffcc00;text-align:left;border:none;width:100%;height:0.2em;">
|
|
83 </div>
|
|
84 </td>
|
|
85 </tr>
|
|
86 </table>
|
|
87 </div>
|
|
88
|
|
89
|
|
90
|
|
91 <div class='slide'>
|
55
|
92 <h3 id="本研究における成果">本研究における成果</h3>
|
|
93 <ul>
|
|
94 <li>並列分散フレームワークChristieをUnityで動作可能に
|
|
95 <ul>
|
|
96 <li>Unity上でp2pを基礎としたオンラインゲームの開発が可能に</li>
|
|
97 </ul>
|
|
98 </li>
|
|
99 <li>Christie Sharpと既存のUnityの通信フレームワークとの機能的な比較を行った
|
|
100 <ul>
|
|
101 <li>Christie Sharpの利点
|
|
102 <ul>
|
|
103 <li>単体でも並列ライブラリとして機能する</li>
|
|
104 <li>通信切断が起こった場合でもゲームロジックが停止しない</li>
|
|
105 </ul>
|
|
106 </li>
|
|
107 </ul>
|
|
108 </li>
|
|
109 </ul>
|
|
110
|
|
111
|
|
112
|
|
113 </div>
|
|
114
|
|
115 <div class='slide'>
|
|
116 <!-- _S9SLIDE_ -->
|
|
117
|
|
118
|
|
119 <h3 id="概要">概要</h3>
|
54
|
120 <ul>
|
|
121 <li>オンラインゲームにおける通信にはクライアントサーバ方式が主流
|
|
122 <ul>
|
|
123 <li>データの共有はサーバを経由するため低速</li>
|
|
124 </ul>
|
|
125 </li>
|
|
126 <li>当研究室で開発を行っているChristie の分散計算を使用することで、高速かつ安全に通信できると考えた</li>
|
|
127 <li>Christie をUnity で使用するためにC# で書き換えを行った</li>
|
|
128 <li>実装としては、localDataGearManager を用いた同一プロセスで複数インスタンス立ち上げによる通信が可能</li>
|
|
129 </ul>
|
|
130
|
|
131
|
|
132
|
|
133 </div>
|
|
134
|
|
135 <div class='slide'>
|
|
136 <!-- _S9SLIDE_ -->
|
|
137
|
|
138
|
|
139 <h3 id="オンラインゲームにおけるデータ通信">オンラインゲームにおけるデータ通信</h3>
|
|
140 <ul>
|
|
141 <li>オンラインゲームは複数のプレイヤーが関与する分散プログラム
|
|
142 <ul>
|
55
|
143 <li>分散プログラムを正しく書くことは難しい
|
|
144 <ul>
|
|
145 <li>ネットワークの変化、故障、性能の多様性を吸収する</li>
|
|
146 <li>スケーラビリティー リソースの追加のみでサービスの質の直感的に維持できる性能基準</li>
|
|
147 </ul>
|
|
148 </li>
|
|
149 <li>Debugも困難な場合が多い</li>
|
54
|
150 </ul>
|
|
151 </li>
|
|
152 <li>クライアントの負荷軽減やチート対策のため、クライアントサーバ方式が主流
|
|
153 <ul>
|
55
|
154 <li>データの同期にはサーバを経由するためp2pに比べ低速</li>
|
54
|
155 </ul>
|
|
156 </li>
|
|
157 </ul>
|
|
158
|
|
159
|
|
160
|
|
161 </div>
|
|
162
|
|
163 <div class='slide'>
|
|
164 <!-- _S9SLIDE_ -->
|
|
165
|
|
166
|
|
167 <h3 id="オンラインゲームにおけるデータ通信-1">オンラインゲームにおけるデータ通信</h3>
|
|
168 <ul>
|
|
169 <li>当研究室では並列分散通信フレームワークChristie を開発中である
|
|
170 <ul>
|
|
171 <li>型のあるDataGear とKey を持つストリーム、DataGearManager として格納している</li>
|
|
172 <li>他のノードはDGM のproxyを持っており、proxy に書き込むことで通信を実現している</li>
|
|
173 <li>DGM はトポロジーマネージャーによって自動的に構築される
|
|
174 <ul>
|
|
175 <li>プログラム自体はDGM の名前を知っていれば良い</li>
|
|
176 <li>他のノードのIP addressなどを知る必要はない</li>
|
|
177 </ul>
|
|
178 </li>
|
|
179 </ul>
|
|
180 </li>
|
|
181 <li>ネットワークが切断されてもゲームは継続可能</li>
|
55
|
182 <li>
|
|
183 <p>ノードが接続している対象を直接知ることはできない</p>
|
54
|
184 </li>
|
|
185 <li>本研究ではJava で書かれたChristieとC# で書き換えを行ったChristie #を説明し、その機能と実装の差について考察を行う</li>
|
|
186 </ul>
|
|
187
|
|
188
|
|
189
|
|
190 </div>
|
|
191
|
|
192 <div class='slide'>
|
|
193 <!-- _S9SLIDE_ -->
|
|
194
|
|
195
|
|
196 <h3 id="christie-の基礎概念">Christie の基礎概念</h3>
|
|
197 <ul>
|
|
198 <li>Christie は当研究室で開発をしている並列分散通信フレームワークである
|
|
199 <ul>
|
|
200 <li>同じく当研究室で開発しているGearsOS に導入予定のため次のような概念を持っている</li>
|
|
201 </ul>
|
|
202 </li>
|
|
203 <li>CodeGear (クラスやスレッド)</li>
|
|
204 <li>DataGear (変数データ)</li>
|
|
205 <li>CodeGearManager (CG,DG,DGMを管理)</li>
|
|
206 <li>DataGearManager (DGを管理,localとremoteの2種類がある, put操作によりDGを格納)</li>
|
|
207 </ul>
|
|
208
|
|
209
|
|
210
|
|
211 </div>
|
|
212
|
|
213 <div class='slide'>
|
|
214 <!-- _S9SLIDE_ -->
|
|
215
|
|
216
|
|
217 <h3 id="christie-の基礎概念-1">Christie の基礎概念</h3>
|
|
218 <center><img src="https://i.imgur.com/ZvpoXGd.png" alt="message" width="450" height="300" /></center>
|
|
219 <center>
|
|
220 Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図
|
|
221 </center>
|
|
222
|
|
223 <ul>
|
|
224 <li>全てのCGM はThreadPool と他のCGM をList として共有している</li>
|
|
225 <li>ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく
|
|
226 <ul>
|
|
227 <li>1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ</li>
|
|
228 </ul>
|
|
229 </li>
|
|
230 <li>ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能</li>
|
|
231 </ul>
|
|
232
|
|
233
|
|
234
|
|
235 </div>
|
|
236
|
|
237 <div class='slide'>
|
|
238 <!-- _S9SLIDE_ -->
|
|
239
|
|
240
|
|
241 <h3 id="christie-の基礎概念-annotationについて">Christie の基礎概念 annotationについて</h3>
|
|
242 <p>DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。</p>
|
|
243
|
|
244 <ul>
|
|
245 <li>Take
|
|
246 <ul>
|
|
247 <li>先頭のDG を読み込み、そのDG を削除する</li>
|
|
248 <li>DG が複数ある場合Take を使用する</li>
|
|
249 </ul>
|
|
250 </li>
|
|
251 <li>Peek
|
|
252 <ul>
|
|
253 <li>先頭のDG を読み込むがDG を削除しない</li>
|
|
254 <li>操作をしない場合は同じデータを参照し続ける</li>
|
|
255 </ul>
|
|
256 </li>
|
|
257 <li>TakeFrom
|
|
258 <ul>
|
|
259 <li>Take と同じ動作だが、remote 先のDGMを指定できる</li>
|
|
260 </ul>
|
|
261 </li>
|
|
262 <li>PeekFrom
|
|
263 <ul>
|
|
264 <li>Peek と同じ動作だが、remote 先のDGMを指定できる</li>
|
|
265 </ul>
|
|
266 </li>
|
|
267 </ul>
|
|
268
|
|
269
|
|
270
|
|
271 </div>
|
|
272
|
|
273 <div class='slide'>
|
|
274 <!-- _S9SLIDE_ -->
|
|
275
|
|
276
|
|
277 <h3 id="topology-manager">Topology Manager</h3>
|
|
278 <ul>
|
|
279 <li>Christie 上でNetwork Topology を形成する
|
|
280 <ul>
|
|
281 <li>参加を表明したノードに名前を与える</li>
|
|
282 <li>必要があればノード同士の配線を自動で行う</li>
|
|
283 </ul>
|
|
284 </li>
|
|
285 <li>静的Topology と動的Topology 2種類がある</li>
|
|
286 </ul>
|
|
287
|
|
288
|
|
289
|
|
290 </div>
|
|
291
|
|
292 <div class='slide'>
|
|
293 <!-- _S9SLIDE_ -->
|
|
294
|
|
295
|
|
296 <h3 id="topology-manager-1">Topology Manager</h3>
|
|
297 <ul>
|
|
298 <li>静的Topology は以下のようなdot ファイルを与えることでNode の関係を構築できる</li>
|
|
299 <li>それぞれのNode への通信にはIP address などは使用せずright というlabel を使用することで接続できる</li>
|
|
300 </ul>
|
|
301
|
|
302 <pre><code class="language-ring.dot">digraph test {
|
|
303 node0 -> node1 [label="right"]
|
|
304 node1 -> node2 [label="right"]
|
|
305 node2 -> node0 [label="right"]
|
|
306 }
|
|
307 </code></pre>
|
|
308
|
|
309 <center><img src="https://i.imgur.com/pCCHo2W.png" alt="message" width="200" height="300" /></center>
|
|
310 <center></center>
|
|
311
|
|
312 <!---
|
|
313
|
|
314 ---
|
|
315
|
|
316 ### Christie のコード例
|
|
317
|
|
318 ``` java:StartHelloWorld.java
|
|
319 public class StartHelloWorld extends StartCodeGear {
|
|
320
|
|
321 public StartHelloWorld(CodeGearManager cgm) {
|
|
322 super(cgm);
|
|
323 }
|
|
324
|
|
325 public static void main(String[] args){
|
|
326 CodeGearManager cgm = createCGM(10000);
|
|
327 cgm.setup(new HelloWorldCodeGear());
|
|
328 cgm.setup(new FinishHelloWorld());
|
|
329 cgm.getLocalDGM().put("helloWorld","hello");
|
|
330 cgm.getLocalDGM().put("helloWorld","world");
|
|
331 }
|
|
332 }
|
|
333 ```
|
|
334
|
|
335 ```java:HelloWorldCodeGear.java
|
|
336 public class HelloWorldCodeGear extends CodeGear {
|
|
337
|
|
338 @Take String helloWorld;
|
|
339
|
|
340 @Override
|
|
341 protected void run(CodeGearManager cgm) {
|
|
342 System.out.print(helloWorld + " ");
|
|
343 cgm.setup(new HelloWorldCodeGear());
|
|
344 cgm.getLocalDGM().put(helloWorld,helloWorld);
|
|
345 }
|
|
346 }
|
|
347 ```
|
|
348
|
|
349 ```java:FinishHelloWorld.java
|
|
350 public class FinishHelloWorld extends CodeGear {
|
|
351 @Take String hello;
|
|
352 @Take String world;
|
|
353
|
|
354 @Override
|
|
355 protected void run(CodeGearManager cgm) {
|
|
356 cgm.getLocalDGM().finish();
|
|
357 }
|
|
358 }
|
|
359 ```
|
|
360 --->
|
|
361
|
|
362
|
|
363
|
|
364 </div>
|
|
365
|
|
366 <div class='slide'>
|
|
367 <!-- _S9SLIDE_ -->
|
|
368
|
|
369
|
|
370 <h3 id="java-からの変更点">Java からの変更点</h3>
|
|
371 <ul>
|
|
372 <li>Java とC# は基本的に書き方は変わらない</li>
|
|
373 </ul>
|
|
374
|
|
375 <pre><code class="language-java:ex.java">Java
|
|
376 public class StartHelloWorld extends StartCodeGear { }
|
|
377
|
|
378 @Override
|
|
379 protected void run(CodeGearManager cgm) { }
|
|
380
|
|
381 @Take String helloWorld;
|
|
382 </code></pre>
|
|
383
|
|
384 <pre><code class="language-cs:ex.cs">C#
|
|
385 public class StartHelloWorld : StartCodeGear { }
|
|
386
|
|
387 public override void Run(CodeGearManager cgm) { }
|
|
388
|
|
389 [Take] string helloWorld;
|
|
390 </code></pre>
|
|
391
|
|
392
|
|
393
|
|
394 </div>
|
|
395
|
|
396 <div class='slide'>
|
|
397 <!-- _S9SLIDE_ -->
|
|
398
|
|
399
|
|
400 <h3 id="christie--のコード例">Christie # のコード例</h3>
|
|
401 <pre><code class="language-cs:StartHelloWorld.cs">public class StartHelloWorld : StartCodeGear {
|
|
402
|
|
403 public StartHelloWorld(CodeGearManager cgm) : base(cgm) { }
|
|
404
|
|
405 public static void Main(string[] args) {
|
|
406 CodeGearManager cgm = CreateCgm(10000);
|
|
407 cgm.Setup(new HelloWorldCodeGear());
|
|
408 cgm.Setup(new FinishHelloWorld());
|
|
409 cgm.GetLocalDGM().Put("helloWorld", "hello");
|
|
410 cgm.GetLocalDGM().Put("helloWorld", "world");
|
|
411 }
|
|
412 }
|
|
413 </code></pre>
|
|
414
|
|
415 <pre><code class="language-cs:HelloWorldCodeGear.cs">public class HelloWorldCodeGear : CodeGear {
|
|
416 [Take] string helloWorld;
|
|
417
|
|
418 public override void Run(CodeGearManager cgm) {
|
|
419 Console.Write(helloWorld + " ");
|
|
420 cgm.Setup(new HelloWorldCodeGear());
|
|
421 cgm.GetLocalDGM().Put(helloWorld, helloWorld);
|
|
422 }
|
|
423 }
|
|
424 </code></pre>
|
|
425
|
|
426 <pre><code class="language-cs:FinishHelloWorld.cs">public class FinishHelloWorld : CodeGear {
|
|
427 [Take] private string hello;
|
|
428 [Take] private string world;
|
|
429
|
|
430 public override void Run(CodeGearManager cgm) {
|
|
431 cgm.GetLocalDGM().Finish();
|
|
432 }
|
|
433 }
|
|
434 </code></pre>
|
|
435
|
|
436 <ol>
|
|
437 <li>Main関数でCGM のインスタンス生成</li>
|
|
438 <li>2つのCG をsetupして待ち状態にする</li>
|
|
439 <li>key:hellowWorld data:”hello” がTake される</li>
|
|
440 <li>変数が揃ったためStartHelloWorld のRun が実行される</li>
|
|
441 <li>“hello” がprintされ、再び待ち状態になる。 key:hellow data:”hello”がput される</li>
|
|
442 <li>key:hellowWorld data:”world” がTake され、4,5と同様に処理される</li>
|
|
443 <li>変数hello とworld がput され揃ったため、FinishHelloWorld のRun が実行され、プログラムは終了する</li>
|
|
444 </ol>
|
|
445
|
|
446 <h3 id="unity">Unity</h3>
|
|
447 <ul>
|
|
448 <li>UnityはUnity Technologies が開発を行っているゲームエンジンである
|
|
449 <ul>
|
|
450 <li>世界で最も使用されているゲームエンジン</li>
|
|
451 <li>非常に軽く、スペックが低いノートPCでもゲーム開発が可能</li>
|
|
452 </ul>
|
|
453 </li>
|
|
454 <li>プログラミング言語にはC# が採用されている
|
|
455 <ul>
|
|
456 <li>C# のAPI やUnity 向けに拡張されたAPIも使用可能</li>
|
|
457 <li>開発した機能をUnity に組み込むことも可能</li>
|
|
458 </ul>
|
|
459 </li>
|
|
460 </ul>
|
|
461
|
|
462
|
|
463
|
|
464 </div>
|
|
465
|
|
466 <div class='slide'>
|
|
467 <!-- _S9SLIDE_ -->
|
|
468
|
|
469
|
|
470 <h3 id="christie--on-unityのコード例">Christie # on Unityのコード例</h3>
|
|
471 <pre><code class="language-cs:UnityStartHelloWorld.cs">public class StartHelloWorld : StartCodeGear {
|
|
472
|
|
473 public StartHelloWorld(CodeGearManager cgm) : base(cgm) { }
|
|
474
|
|
475 public void RunCodeGear(CodeGearManager cgm) {
|
|
476 cgm.Setup(new HelloWorldCodeGear());
|
|
477 cgm.Setup(new FinishHelloWorld());
|
|
478 cgm.GetLocalDGM().Put("helloWorld", "hello");
|
|
479 cgm.GetLocalDGM().Put("helloWorld", "world");
|
|
480 }
|
|
481 }
|
|
482 </code></pre>
|
|
483
|
|
484 <pre><code class="language-cs:UnityHelloWorld.cs">public class HelloWorld : MonoBehaviour {
|
|
485 void Start() {
|
|
486 CodeGearManager cgm = StartCodeGear.CreateCgm(10000);
|
|
487 var helloWorld = new StartHelloWorld(cgm);
|
|
488 helloWorld.RunCodeGear(cgm);
|
|
489 }
|
|
490 }
|
|
491 </code></pre>
|
|
492 <ul>
|
|
493 <li>HelloWorldCodeGearと、FinishHelloWorld はそのまま使用</li>
|
|
494 <li>StartHelloWorld をUnity で使用できるように書き換え
|
|
495 <ul>
|
|
496 <li>Unity ではMonoBehaviour 継承したクラスが動作可能</li>
|
|
497 <li>ゲーム開始時に1度だけ呼ばれるStart 関数</li>
|
|
498 <li>Start 関数でCGM のインスタンスを生成</li>
|
|
499 <li>Main 関数を名前を変えたRunCodeGear 関数を実行</li>
|
|
500 </ul>
|
|
501 </li>
|
|
502 </ul>
|
|
503
|
|
504
|
|
505
|
|
506 </div>
|
|
507
|
|
508 <div class='slide'>
|
|
509 <!-- _S9SLIDE_ -->
|
|
510
|
|
511
|
|
512 <h3 id="take-annotationの実装">Take annotationの実装</h3>
|
|
513 <ul>
|
|
514 <li>Christie ではDGを取得するためにannotation を使用している
|
|
515 <ul>
|
|
516 <li>C# ではannotation と同様の機能にattribute があり、Take をattribute で実装した</li>
|
|
517 </ul>
|
|
518 </li>
|
|
519 <li>Take はフィールド変数に対して適用する</li>
|
|
520 </ul>
|
|
521
|
|
522 <pre><code class="language-java:Take.java">@Target(ElementType.FIELD)
|
|
523 @Retention(RetentionPolicy.RUNTIME)
|
|
524 public @interface Take { }
|
|
525 </code></pre>
|
|
526
|
|
527 <pre><code class="language-cs:Take.cs">[AttributeUsage(AttributeTargets.Field)]
|
|
528 public class Take : Attribute { }
|
|
529 </code></pre>
|
|
530
|
|
531
|
|
532
|
|
533 </div>
|
|
534
|
|
535 <div class='slide'>
|
|
536 <!-- _S9SLIDE_ -->
|
|
537
|
|
538
|
|
539 <h3 id="messagepackの相違点">MessagePackの相違点</h3>
|
|
540 <ul>
|
|
541 <li>Christie ではMessagePack を使用してデータを圧縮し送受信している
|
|
542 <ul>
|
|
543 <li>インスタンス内のpublic 変数に対して圧縮可能</li>
|
|
544 </ul>
|
|
545 </li>
|
|
546 <li>バージョンが古いため、現在はサポートされていない
|
|
547 <ul>
|
|
548 <li>そのため、最新版とは記述方法が異なる</li>
|
|
549 </ul>
|
|
550 </li>
|
|
551 <li>圧縮するクラスには@Message annotatoinをつける</li>
|
|
552 <li>MessagePack インスタンスを作成後、write、read することでデータの圧縮解凍が可能
|
|
553 <ul>
|
|
554 <li>圧縮されたデータはbyte[] 型になる</li>
|
|
555 </ul>
|
|
556 </li>
|
|
557 </ul>
|
|
558
|
|
559 <pre><code class="language-java:MessagePackEx.java">public class MessagePackExample {
|
|
560 @Message
|
|
561 public static class MyMessage {
|
|
562 public String name;
|
|
563 public double version;
|
|
564 }
|
|
565
|
|
566 public static void main(String[] args) throws Exception {
|
|
567 MyMessage src = new MyMessage();
|
|
568 src.name = "msgpack";
|
|
569 src.version = 0.6;
|
|
570
|
|
571 MessagePack msgpack = new MessagePack();
|
|
572 // Serialize
|
|
573 byte[] bytes = msgpack.write(src);
|
|
574 // Deserialize
|
|
575 MyMessage dst = msgpack.read(bytes, MyMessage.class);
|
|
576 }
|
|
577 }
|
|
578 </code></pre>
|
|
579
|
|
580
|
|
581
|
|
582 </div>
|
|
583
|
|
584 <div class='slide'>
|
|
585 <!-- _S9SLIDE_ -->
|
|
586
|
|
587
|
|
588 <h3 id="messagepackの相違点-1">MessagePackの相違点</h3>
|
|
589 <ul>
|
|
590 <li>C# のMessagePack は複数存在している
|
|
591 <ul>
|
|
592 <li>java 版と似たような書き方をするMessagePack-CSharp を選択した</li>
|
|
593 </ul>
|
|
594 </li>
|
|
595 <li>圧縮を行いたいクラスに対してMessagePackObject attribute を付ける</li>
|
|
596 <li>圧縮する変数に対してkey を設定できる
|
|
597 <ul>
|
|
598 <li>解凍時にjson として展開できる</li>
|
|
599 </ul>
|
|
600 </li>
|
|
601 <li>データの圧縮にはMessagePackSerializer.Serialize 関数を用い、byte[] に圧縮される</li>
|
|
602 <li>データの解凍にはMessagePackSerializer.Deserialize 関数を使用する
|
|
603 <ul>
|
|
604 <li>Deserialize 関数はジェネリスク関数であるため<>内に解凍するデータの型情報を記述する</li>
|
|
605 </ul>
|
|
606 </li>
|
|
607 </ul>
|
|
608
|
|
609 <pre><code class="language-cs.MessagePackEx.cs">[MessagePackObject]
|
|
610 public class MyClass {
|
|
611 [Key(0)]
|
|
612 public int Age { get; set; }
|
|
613 [Key(1)]
|
|
614 public string FirstName { get; set; }
|
|
615 [Key(2)]
|
|
616 public string LastName { get; set; }
|
|
617
|
|
618 static void Main(string[] args) {
|
|
619 var mc = new MyClass {
|
|
620 Age = 99,
|
|
621 FirstName = "hoge",
|
|
622 LastName = "huga",
|
|
623 };
|
|
624
|
|
625 byte[] bytes = MessagePackSerializer.Serialize(mc);
|
|
626 MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);
|
|
627
|
|
628 // [99,"hoge","huga"]
|
|
629 var json = MessagePackSerializer.ConvertToJson(bytes);
|
|
630 Console.WriteLine(json);
|
|
631 }
|
|
632 }
|
|
633 </code></pre>
|
|
634
|
|
635
|
|
636
|
|
637 </div>
|
|
638
|
|
639 <div class='slide'>
|
|
640 <!-- _S9SLIDE_ -->
|
|
641
|
|
642
|
|
643 <h3 id="threadpoolからtaskへの書き換え">ThreadPoolからTaskへの書き換え</h3>
|
|
644 <ul>
|
|
645 <li>Christie ではThreadPool を使用していた
|
|
646 <ul>
|
|
647 <li>Christie # ではThreadPoolより高機能なTask を用いて書き換えを行った</li>
|
|
648 </ul>
|
|
649 </li>
|
|
650 <li>
|
|
651 <p>Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる</p>
|
|
652 </li>
|
|
653 <li>裏でThreadPool が動くようになっている
|
|
654 <ul>
|
|
655 <li>大きく動作は変わらない</li>
|
|
656 </ul>
|
|
657 </li>
|
|
658 </ul>
|
|
659
|
|
660
|
|
661
|
|
662 </div>
|
|
663
|
|
664 <div class='slide'>
|
|
665 <!-- _S9SLIDE_ -->
|
|
666
|
|
667
|
|
668 <h3 id="threadpoolからtaskへの書き換え-1">ThreadPoolからTaskへの書き換え</h3>
|
|
669
|
|
670 <pre><code class="language-java:PriorityThreadPoolExecutors.java">public class PriorityThreadPoolExecutors {
|
|
671
|
|
672 private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
|
|
673 private static final int DEFAULT_PRIORITY = 0;
|
|
674 private static AtomicLong instanceCounter = new AtomicLong();
|
|
675
|
|
676 public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
|
|
677 int keepAliveTime, TimeUnit unit) {
|
|
678 super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue<ComparableTask>(10,
|
|
679 ComparableTask.comparatorByPriorityAndSequentialOrder()));
|
|
680 }
|
|
681
|
|
682 @Override
|
|
683 public void execute(Runnable command) {
|
|
684 super.execute(command);
|
|
685 }
|
|
686 }
|
|
687 }
|
|
688 </code></pre>
|
|
689
|
|
690 <pre><code class="language-cs:ThreadPoolExecuters.cs">public class ThreadPoolExecutors {
|
|
691
|
|
692 public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) {
|
|
693 ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads);
|
|
694 }
|
|
695
|
|
696 public void Execute(CodeGearExecutor command) {
|
|
697 Task.Factory.StartNew(() => command.Run());
|
|
698 }
|
|
699 }
|
|
700 </code></pre>
|
|
701
|
|
702
|
|
703
|
|
704 </div>
|
|
705
|
|
706 <div class='slide'>
|
|
707 <!-- _S9SLIDE_ -->
|
|
708
|
|
709
|
|
710 <h3 id="unityで使用されているライブラリとの比較">Unityで使用されているライブラリとの比較</h3>
|
|
711 <p>Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、MLAPIと、Christie # の比較を行う。</p>
|
|
712
|
|
713 <table>
|
|
714 <thead>
|
|
715 <tr>
|
|
716 <th> </th>
|
|
717 <th>Christie #</th>
|
|
718 <th>PUN2</th>
|
|
719 <th>MLAPI</th>
|
|
720 </tr>
|
|
721 </thead>
|
|
722 <tbody>
|
|
723 <tr>
|
|
724 <td>通信方式</td>
|
|
725 <td>p2p</td>
|
|
726 <td>クライアントサーバ方式</td>
|
|
727 <td>クライアントサーバ方式</td>
|
|
728 </tr>
|
|
729 <tr>
|
|
730 <td>プロトコル</td>
|
|
731 <td>TCP</td>
|
|
732 <td>TCP</td>
|
|
733 <td>TCP</td>
|
|
734 </tr>
|
|
735 <tr>
|
|
736 <td>特徴</td>
|
|
737 <td>通信のためのIP address がプログラム直接記述されていない</td>
|
|
738 <td>Photon Cloud でサーバを自前で用意する必要がない</td>
|
|
739 <td>Unity公式でサポートされている RPC が使用可能</td>
|
|
740 </tr>
|
|
741 </tbody>
|
|
742 </table>
|
|
743
|
|
744
|
|
745
|
|
746 </div>
|
|
747
|
|
748 <div class='slide'>
|
|
749 <!-- _S9SLIDE_ -->
|
|
750
|
|
751
|
|
752 <h3 id="チート対策について">チート対策について</h3>
|
|
753 <ul>
|
|
754 <li>オンラインゲームにおいてチート対策は必須</li>
|
|
755 <li>通常のオンラインゲームでのチート対策
|
|
756 <ul>
|
|
757 <li>クライアントをモニタリングする</li>
|
|
758 <li>ダメージ計算などは全てサーバで行う</li>
|
|
759 <li>ユーザからの通報</li>
|
|
760 </ul>
|
|
761 </li>
|
|
762 <li>Christie では型があるDataGear をkey と合わせてDGMに格納する方式を取っている
|
|
763 <ul>
|
|
764 <li>他のノードとの通信にはDGM のporxy に書き込むことで可能</li>
|
|
765 <li>DGM の構成にはTopology Manager が自動的に構成する</li>
|
|
766 </ul>
|
|
767 </li>
|
|
768 <li>Topology Manager を使用することでクライアントは接続先を直接知る必要がない
|
|
769 <ul>
|
|
770 <li>IP address などチートに使用される情報をプログラムに含めることなく通信可能</li>
|
|
771 </ul>
|
|
772 </li>
|
|
773 </ul>
|
|
774
|
|
775 <center><img src="https://i.imgur.com/L8GVFdL.png" alt="message" width="450" height="260" /></center>
|
|
776 <center>label を使用したデータ通信</center>
|
|
777
|
|
778 <h3 id="実装の現状">実装の現状</h3>
|
|
779 <ul>
|
|
780 <li>Local DGMを使用してUnity 上でデータ通信を行うことができている</li>
|
|
781 <li>Scketo とMessagePack を用いた通信に関しては、書き換え途中
|
|
782 <ul>
|
|
783 <li>独自クラスをMessagePack でserialize できない</li>
|
|
784 </ul>
|
|
785 </li>
|
|
786 <li>今後の予定
|
|
787 <ul>
|
|
788 <li>Christie で実装されている例題</li>
|
|
789 <li>Alice からChristie に書き換えた際に取り除かれた機能の洗い出しを行う</li>
|
|
790 <li>Unity でChristie #の検証として100人規模のFPS の作成</li>
|
|
791 </ul>
|
|
792 </li>
|
|
793 </ul>
|
|
794
|
|
795
|
|
796
|
|
797 </div>
|
|
798
|
|
799 <div class='slide'>
|
|
800 <!-- _S9SLIDE_ -->
|
|
801
|
|
802
|
|
803 <h3 id="まとめ">まとめ</h3>
|
|
804 <ul>
|
|
805 <li>Christie をUnity で使用するためにC# に書き換えを行った</li>
|
|
806 <li>書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同一になるようにした</li>
|
|
807 <li>実装としては、localDataGearManager を用いた同一プロセスで複数インスタンス立ち上げによる通信が可能</li>
|
|
808 <li>Remote DataGearManager を使用した複数台の通信については書き換え途中であり、引き続き行っていく</li>
|
|
809 <li>Christie の検証のためUnity で100人規模のFPS を作成する</li>
|
|
810 </ul>
|
|
811
|
|
812
|
|
813 </div>
|
|
814
|
|
815
|
|
816 </div><!-- presentation -->
|
|
817 </body>
|
|
818 </html>
|