Mercurial > hg > Papers > 2022 > riono-master
changeset 46:67306bcc605a
rename flie
author | riono <e165729@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 10 Feb 2022 10:50:37 +0900 |
parents | 4a1a9a0fe1ce |
children | 9c38517457d6 |
files | Paper/chapter/3-ChristieSharp.tex Paper/chapter/3-WorkingInUnity.tex Paper/chapter/4-LibraryComparison.tex Paper/chapter/4-WorkingInUnity.tex Paper/chapter/5-LibraryComparison.tex Paper/chapter/conclusion.tex |
diffstat | 6 files changed, 203 insertions(+), 201 deletions(-) [+] |
line wrap: on
line diff
--- a/Paper/chapter/3-ChristieSharp.tex Thu Feb 10 10:16:06 2022 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -\chapter{Christie Sharp}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/chapter/3-WorkingInUnity.tex Thu Feb 10 10:50:37 2022 +0900 @@ -0,0 +1,135 @@ +\chapter{Christie SharpのUnity上での動作} + +\section{Unity API} +Unityでは、ゲーム開発を行うためのライブラリとしてUnity APIが公開されている。 +ソースコード\ref{src:UnityExample}はUnity APIを使用したスクリプトの例である。 +Spaceキーを押し続けている間、playerObjectは物理演算に従って、毎フレーム$\vec{A} = (10, 5, 10)$だけ力を加えられ移動する例である。 +4行目では変数が初期化されていないまま使用されているように見えるが、Unityではpublic修飾子を使用するとUnityのエディタ上で事前に変数に代入することが可能になる。 + +\lstinputlisting[label=src:UnityExample, caption=Unity APIを使用した記述例]{src/Unity/UnityScriptExample.cs} + +Unity APIではC\#にはないVector3やGameObject、Rigidbodyなどの特別な型があり、これらはUnityEngineをusingすることで使用可能である。 +またMonoBehaviourを継承することによって、StartメソッドやUpdateメソッドなどのUnity上で決められた、あるタイミングで呼び出される関数を使用することが可能である。 + + +Startメソッドはゲームの開始時、1フレーム目が始まる前に1回だけ実行され、主に初期化に使用されることが多い。 +今回はplayerObjectに付与されている物理演算のComponentであるRigidbodyを取得している。 + + +UpdateメソッドはStartメソットの実行後に毎フレーム呼び出される関数であり、ゲームのメインロジックで使用されることが多い。 +15行目ではキー入力の有無を確認しており、Spaceキーの入力を監視している。 +続く16行目では、Startメソッドにて取得したRigidbodyに対して、3次元ベクトルを力として与えている。 +これを行うことによって、Spaceキーを押している間$\vec{A} = (10, 5, 10)$がplayerObjectに与えられ、playerObjectは物理演算に従って移動する。 + + +UnityではStartメソッドやUpdateメソッドがある代わりに、C\#の一般的な実行メソッドであるMainメソッドによる処理の開始ができない。 +そのため、Unityで処理を行うためには、MonoBehaviourにより提供されているメソッドを通して処理を実行する必要がある。 + + +\section{StartCodeGearを使用しないChristie Sharpの実行} +% 例題など +% やったこと全部書いたほうがいい/できたこと +% 多重継承の話 + +Chrisite SharpではStartCGにMainメソッドを記述してChrisite Sharpを実行したが、Unityで動作させるためにはStartメソッドやUpdeteメソッドを使用す必要がある。 +そのため、Chrisite Sharpの実行にStartCGを使用せずに実行できるよう変更を行った。 + +\lstinputlisting[label=src:CountUpScript, caption=Unit上でのChrisite Sharpの実行Script]{src/Unity/CountUpScript.cs} + +ソースコード\ref{src:CountUpScript}はソースコード\ref{src:CSStartCGExample}をUnityで動作するように書き換えたものであり、StartCGを使用せずに、Unity APIであるStartメソッドよりChrisite Sharpを実行している。 +StartCGは、CGMの初期化や処理の開始位置を明確化させるためのクラスであるため、Christie Sharpの実行に必須ではない。 +また、C\#では多重継承が禁止されている。そのため、StartCGを継承しつつ、MonoBehaviourを継承してStartメソッドを使用する、と言うことはできない。 +そのため可読性が下がってしまう可能性はあるが、CGMの初期化やSetupメソッドを直接Startメソッド内に記述できる。 + + +\section{Unity上での動作確認} +% RemoteDG使ったやつ +% 2台で通信した場合 +% LateUpdateの話 +% UniRXのDispatcherとUnity APIの仕様の話 + +Christie Sharptの動作確認を行うため、以下の3点の確認を行った。 +LocalDGMに関してはソースコード\ref{src:CountUpScript}で正しく動作することを確認している。 + +\begin{itemize} + \item CodeGearを使用した、GameObjectの位置の操作 + \item 同一プロセスでの、複数DGMを使用したGameObjectの位置の同期 + \item PC2台を使用した、LAN上でのGameObjectの位置の同期 +\end{itemize} + + +\lstinputlisting[label=src:TransformMoveTest, caption=GameObjectの位置の操作の準備を行うScript]{src/Unity/TransformMoveTest.cs} +\lstinputlisting[label=src:PositionAssignCodeGear, caption=GameObjectの位置の操作を行うCodeGear]{src/Unity/PositionAssignCodeGear.cs} + +ソースコード\ref{src:TransformMoveTest}、\ref{src:PositionAssignCodeGear}は、CodeGearを使用した、GameObjectの位置の操作を行う処理である。 +ソースコード\ref{src:TransformMoveTest}を付与したGameObjectの位置より、常にx軸に+3、z軸に+3離れた位置に他のGameObjectであるotherTransfromが移動をする。 +19行目のLateUpdateメソッドはMonoBehaviourから継承している関数であり、全てのUpdateメソッドが実行された後、次のフレームに移行する直前に実行される関数である。 + +UnityでChrisite Sharpを使用する際に一つ問題が起きた。 +Unity APIでサポートされている関数や型はMain Threadで動作時のみ処理が行われるという仕様がある。 +これはUnityの根本的な考え方であり、Unityでは基本的にシングルスレッドでの動作を想定してる。 +非同期処理を行うための機能として、CoroutineやInvoceなどの機能が提供されており、擬似的にMulti Threadのように処理を行うことが可能である。 +しかしChrisite SharpではCodeGearをTaskで処理させている。 +このためCGに直接Transformを操作しても処理が実行されない。 + + +この問題を解決するために、UniRxを導入することで使用可能なMainThreadDispatcher.Postメソッドを使用した(ソースコード\ref{src:PositionAssignCodeGear} 6行目)。 +UniRxとはUnity向けに作成された非同期処理の外部ライブラリである。 +MainThreadDispatcher.Postを使用することで、Main ThreadでないThreadで行っている処理をMain Threadに移譲することが可能となる。 +Postメソッドは第一引数にデリゲートの一種であるAction$<$T$>$を渡すため、ラムダ式での記述が可能である。 + + +\lstinputlisting[label=src:RemoteMoveTest, caption=RemoteDGMでGameObjectの位置の操作の準備を行うScript]{src/Unity/RemoteMoveTest.cs} +\lstinputlisting[label=src:ObjectMoveCodeGear, caption=RemoteDGMでGameObjectの位置の操作を行うCodeGear]{src/Unity/ObjectMoveCodeGear.cs} +\lstinputlisting[label=src:Vector3Cmd, caption=GameObjectの位置データとして送信されるオブジェクトのクラス]{src/Unity/Vector3Cmd.cs} + +ソースコード\ref{src:RemoteMoveTest}、\ref{src:ObjectMoveCodeGear}、\ref{src:Vector3Cmd}は同一プロセスにおいて、 +RemoteDGMを使用しGameObjectの位置を操作するScriptである。 + +ソースコード\ref{src:RemoteMoveTest}のStartメソッドでは、playerCGMとenemyCGMの2つのDGMを用意し、 +playerCGMの方では他方のenemyCGMをRemoteDGMとして指定を行っている。 +また、enemyCGMではSetupを行い処理の待機状態にしている。 +Updateメソッドでは、このScriptが付与されたGameObjectの位置を取得し、x軸に+3、z軸に+3離れた位置にotherTransformを移動させるようにし、 +送信用クラスに変形を行っている。 +21行目ではotherTransformを持っているenemyCGMではなく、playerCGMからPutを行っている。 + +MessagePack CSharpではUnityにも対応しており、Unity APIが提供している値型のVector3やQuaternionなどもSerialize/Deserialize可能である。 +しかし、Christie SharpではDGでデータを管理する際に全ての型に対応できるようObject型にCastをしている。 +このObject型のCastが原因によりVector3型を直接送信することができない。 +そのため、ソースコード\ref{src:Vector3Cmd}のようにデータをプリミティブ型に分割してデータを送信している。 + +ソースコード\ref{src:ObjectMoveCodeGear}はソースコード\ref{src:PositionAssignCodeGear}と同様にMainThreadDispatcher.Postによって、 +処理はMain Threadに移譲されて実行される。 + + +\lstinputlisting[label=src:ObjectMoveServer, caption=GameObjectの位置をRemoteDGMに送信するScript]{src/Unity/ObjectMoveServer.cs} +\lstinputlisting[label=src:ObjectMoveListener, caption=GameObjectの位置を受信して位置を操作するScript]{src/Unity/ObjectMoveListener.cs} + + +ソースコード\ref{src:ObjectMoveServer}、\ref{src:ObjectMoveListener}は2台のPCを使用しLAN内でGameObjectの位置を通信して操作するScriptである。 +CGや、送信するDGについては、ソースコード\ref{src:ObjectMoveCodeGear}、\ref{src:Vector3Cmd}を流用している。 + + +ソースコード\ref{src:ObjectMoveServer}、\ref{src:ObjectMoveListener}それぞれの3行目ではhostNameを指定しており、通信先のLocal IPアドレスを入力することでSocket通信を行っている。 +ソースコード\ref{src:ObjectMoveServer}は位置データの送信元であり、RemoteDGMとして指定したlistenerに向けて、自身のGameObjectの位置をPutしている。 +ソースコード\ref{src:ObjectMoveListener}は何もデータをPutしておらず、LateUpdateメソッドでSetupを行うことでソースコード\ref{src:ObjectMoveServer}から受け取ったデータを基にGameObjectの位置を変更している。 + + +以上のテストにより、Chrisite Shrapの機能が問題なくUnity上でも機能することが確認できた。 + +\section{UnityでのChrisite Sharpの役割} +UnityでCodeGearを動作させる場合、特にUnity APIを使用して処理を行う際は、MainThreadDispatcher.Postメソッドを利用してMain Threadに処理を以上する必要がある。 +他方、UnityではUpdateメソッドやFixedUpdateメソッドなどUnityの実装に従って、フレーム単位や時間単位でのメソッド呼び出しが保証されている。 +CG内でMainThreadDispatcher.Postメソッドを使用しGameObjectの移動などのUnity APIを利用した処理を行うことで、処理が行われるタイミングが不安定になることがあると考えられる。 + +そこで、ネットワーク上で通信が必要なものだけをChrisite Sharpで通信を行い、受信データをMonoBehaviourを継承したクラスで処理・動作させるという方法を考えた。 +Unityには非同期処理としてCoroutineやTaskなどがあるが、シングルスレッドでの動作を前提として利用されている。 +この手法を取ることにより、Unity上の処理を行うタイミングが保証されると共に、 +並列処理やデータのやり取りをChristieに一任することができ、Multi Threadによる並列処理が可能となる。 + + +またUnity上で操作、処理を行っているGameObject自体をDGに継続にする、直接的にはDGにすることによってより並列処理などを意識することなくゲーム開発が可能となる。 +GameObject自体をDGにすることにより、通信に必要なデータを送信するためのコードを書かずに待ち合わせが可能となる。 +また、待ち合わせを行っていることによりデータがNullのまま処理を開始することがなくなる。 +位置などの毎フレーム必要なデータや、画面の描画に必要なデータはPeekで取得を行うことで、通信が途中で途切れてしまった場合でもその直前のデータは参照可能であり、 +接続の復帰も行いやすいと考えられる。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Paper/chapter/4-LibraryComparison.tex Thu Feb 10 10:50:37 2022 +0900 @@ -0,0 +1,65 @@ +\chapter{Christie Sharpの評価} + +前章まではChristie Sharpの実装やUnity上での動作について述べた。 +本章では、Unityで使用可能な通信ライブラリであるPhoton Unity Networking2、MirrorとChristie Sharpの比較を行い、 +Unityで使用する場合のChristie Sharpの評価を行う。 + +\section{Christie Sharpと既存ライブラリの比較} + +既存の通信ライブラリとしては前述した、Photon Unity Network2とMirrorをChristie Sharpとの比較を行う。 +表\ref{tb:Libraryfeature}はChrisite Sharp、PUN2、Mirrorのそれぞれの特徴をまとめたものである。 + + +\begin{table}[htbp] + \begin{center} + \caption{各通信ライブラリの特徴} + \begin{tabular}{|c|c|c|c|} \hline %hlineで縦線 |c|で要素をくくる + & node間の通信方法 & Unity APIの対応 & 拡張可能か \\ \hline +Christie Sharp & p2p & 未対応 & 可能\\ \hline +PUN2 & Server Client & 対応 & 一部可能\\ \hline +Mirror & Server Client & 対応 & 可能\\ \hline + \end{tabular} + \label{tb:Libraryfeature} + \end{center} +\end{table} + + +PUN2やMirrorはnode間の通信方法としてクライアントサーバ方式を取っている。 +背景には、PUN2はPhoton Cloudを前提にServerへの接続が行われており、MirrorはMMOでの動作を前提に作成されているからである。 +一方Christie Sharpは、Topology Managerを利用して各nodeの接続を行っているためServerは無く、p2pでの接続となる。 + +Unity APIの対応に関しては、PUN2、MirrorがUnity APIで提供されている独自の型を簡単に同期できる機能があるが、 +Christie Sharpにはその機能が存在せず、データの同期にはC\#のプリミティブ型に変換して送信する必要がある。 + +拡張が可能かについては、Christie Sharp、Mirrorはユーザ自身が拡張可能である。 +Christie SharpはGitHubにて公開予定であり、MirrorはOSSなため、プロジェクトの状況に応じた機能の追加や変更などが可能となっている。 +一方PUN2はUnity上で動作するClient側のソースコードは公開されているが、Server側はPhoton Cloudを使用する必要があるため、拡張性は他の比較対象と比べ低い。 + + +PUN2ではPhoton Cloudがあるが、無料での使用には制限がかかり、制限を超えると別途Serverの料金が発生する。 +Mirrorは自前でServerを用意する必要があり、処理の大半はServerで行われるためServerのスペックを考えて開発する必要があある。 +Chrisite SharpはUnity APIへの対応が未対応が目立つ一方、p2pで通信を行うため、強力なServerを必要としない。 +またp2pの形式を取っているが、Topology ManagerのHostをServerで作動させることで、クライアントサーバ方式に変更することも可能である。 + + +\section{Christie Sharpの利点} +他の通信ライブラリと比較して、Chrisite Sharpを利用する利点として、以下が挙げられる。 + +\begin{itemize} + \item 単体でも並列処理が可能 + \item 通信切断した際にゲームロジックが停止しない +\end{itemize} + +他の通信ライブラリでは、並列処理の外部ライブラリを導入する際に、ライブラリ同士の相性や処理方法について考える必要がある。 +並列処理や非同期処理のDebugは複雑であり、複数のライブラリで問題が起きていた際に特定と解決は困難である。 +Chrisite Sharpでは、CodeGear/DataGearを使用した待ち合わせ処理を基本として処理が行われる。 +この処理はMulti Threadで行われているため、ユーザは並列処理や非同期処理を必要以上に意識せずにプログラムが可能である。 +並列処理のライブラリを導入しなくても済むため、問題の特定は複数のライブラリを組み合わせた場合と比べ容易になる。 + + +node間の通信において、通信の切断は必ず発生する。 +通信が切断された際に、ゲームロジックが破綻しゲーム全体が続行不可能になる場合もある。 + +通常、切断時にゲームロジックが停止しないような例外処理を行う必要があるが、Chrisite Sharpでは常に参照すべき値をPeekで取得することによって、 +通信が切断されても参照データは消えずに参照可能である。 +また、Topology ManagerにはCookieの機能が備わっているため、改良することによって通信が切断された場合にでもゲームに復帰することが可能になると考える。
--- a/Paper/chapter/4-WorkingInUnity.tex Thu Feb 10 10:16:06 2022 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -\chapter{Christie SharpのUnity上での動作} - -\section{Unity API} -Unityでは、ゲーム開発を行うためのライブラリとしてUnity APIが公開されている。 -ソースコード\ref{src:UnityExample}はUnity APIを使用したスクリプトの例である。 -Spaceキーを押し続けている間、playerObjectは物理演算に従って、毎フレーム$\vec{A} = (10, 5, 10)$だけ力を加えられ移動する例である。 -4行目では変数が初期化されていないまま使用されているように見えるが、Unityではpublic修飾子を使用するとUnityのエディタ上で事前に変数に代入することが可能になる。 - -\lstinputlisting[label=src:UnityExample, caption=Unity APIを使用した記述例]{src/Unity/UnityScriptExample.cs} - -Unity APIではC\#にはないVector3やGameObject、Rigidbodyなどの特別な型があり、これらはUnityEngineをusingすることで使用可能である。 -またMonoBehaviourを継承することによって、StartメソッドやUpdateメソッドなどのUnity上で決められた、あるタイミングで呼び出される関数を使用することが可能である。 - - -Startメソッドはゲームの開始時、1フレーム目が始まる前に1回だけ実行され、主に初期化に使用されることが多い。 -今回はplayerObjectに付与されている物理演算のComponentであるRigidbodyを取得している。 - - -UpdateメソッドはStartメソットの実行後に毎フレーム呼び出される関数であり、ゲームのメインロジックで使用されることが多い。 -15行目ではキー入力の有無を確認しており、Spaceキーの入力を監視している。 -続く16行目では、Startメソッドにて取得したRigidbodyに対して、3次元ベクトルを力として与えている。 -これを行うことによって、Spaceキーを押している間$\vec{A} = (10, 5, 10)$がplayerObjectに与えられ、playerObjectは物理演算に従って移動する。 - - -UnityではStartメソッドやUpdateメソッドがある代わりに、C\#の一般的な実行メソッドであるMainメソッドによる処理の開始ができない。 -そのため、Unityで処理を行うためには、MonoBehaviourにより提供されているメソッドを通して処理を実行する必要がある。 - - -\section{StartCodeGearを使用しないChristie Sharpの実行} -% 例題など -% やったこと全部書いたほうがいい/できたこと -% 多重継承の話 - -Chrisite SharpではStartCGにMainメソッドを記述してChrisite Sharpを実行したが、Unityで動作させるためにはStartメソッドやUpdeteメソッドを使用す必要がある。 -そのため、Chrisite Sharpの実行にStartCGを使用せずに実行できるよう変更を行った。 - -\lstinputlisting[label=src:CountUpScript, caption=Unit上でのChrisite Sharpの実行Script]{src/Unity/CountUpScript.cs} - -ソースコード\ref{src:CountUpScript}はソースコード\ref{src:CSStartCGExample}をUnityで動作するように書き換えたものであり、StartCGを使用せずに、Unity APIであるStartメソッドよりChrisite Sharpを実行している。 -StartCGは、CGMの初期化や処理の開始位置を明確化させるためのクラスであるため、Christie Sharpの実行に必須ではない。 -また、C\#では多重継承が禁止されている。そのため、StartCGを継承しつつ、MonoBehaviourを継承してStartメソッドを使用する、と言うことはできない。 -そのため可読性が下がってしまう可能性はあるが、CGMの初期化やSetupメソッドを直接Startメソッド内に記述できる。 - - -\section{Unity上での動作確認} -% RemoteDG使ったやつ -% 2台で通信した場合 -% LateUpdateの話 -% UniRXのDispatcherとUnity APIの仕様の話 - -Christie Sharptの動作確認を行うため、以下の3点の確認を行った。 -LocalDGMに関してはソースコード\ref{src:CountUpScript}で正しく動作することを確認している。 - -\begin{itemize} - \item CodeGearを使用した、GameObjectの位置の操作 - \item 同一プロセスでの、複数DGMを使用したGameObjectの位置の同期 - \item PC2台を使用した、LAN上でのGameObjectの位置の同期 -\end{itemize} - - -\lstinputlisting[label=src:TransformMoveTest, caption=GameObjectの位置の操作の準備を行うScript]{src/Unity/TransformMoveTest.cs} -\lstinputlisting[label=src:PositionAssignCodeGear, caption=GameObjectの位置の操作を行うCodeGear]{src/Unity/PositionAssignCodeGear.cs} - -ソースコード\ref{src:TransformMoveTest}、\ref{src:PositionAssignCodeGear}は、CodeGearを使用した、GameObjectの位置の操作を行う処理である。 -ソースコード\ref{src:TransformMoveTest}を付与したGameObjectの位置より、常にx軸に+3、z軸に+3離れた位置に他のGameObjectであるotherTransfromが移動をする。 -19行目のLateUpdateメソッドはMonoBehaviourから継承している関数であり、全てのUpdateメソッドが実行された後、次のフレームに移行する直前に実行される関数である。 - -UnityでChrisite Sharpを使用する際に一つ問題が起きた。 -Unity APIでサポートされている関数や型はMain Threadで動作時のみ処理が行われるという仕様がある。 -これはUnityの根本的な考え方であり、Unityでは基本的にシングルスレッドでの動作を想定してる。 -非同期処理を行うための機能として、CoroutineやInvoceなどの機能が提供されており、擬似的にMulti Threadのように処理を行うことが可能である。 -しかしChrisite SharpではCodeGearをTaskで処理させている。 -このためCGに直接Transformを操作しても処理が実行されない。 - - -この問題を解決するために、UniRxを導入することで使用可能なMainThreadDispatcher.Postメソッドを使用した(ソースコード\ref{src:PositionAssignCodeGear} 6行目)。 -UniRxとはUnity向けに作成された非同期処理の外部ライブラリである。 -MainThreadDispatcher.Postを使用することで、Main ThreadでないThreadで行っている処理をMain Threadに移譲することが可能となる。 -Postメソッドは第一引数にデリゲートの一種であるAction$<$T$>$を渡すため、ラムダ式での記述が可能である。 - - -\lstinputlisting[label=src:RemoteMoveTest, caption=RemoteDGMでGameObjectの位置の操作の準備を行うScript]{src/Unity/RemoteMoveTest.cs} -\lstinputlisting[label=src:ObjectMoveCodeGear, caption=RemoteDGMでGameObjectの位置の操作を行うCodeGear]{src/Unity/ObjectMoveCodeGear.cs} -\lstinputlisting[label=src:Vector3Cmd, caption=GameObjectの位置データとして送信されるオブジェクトのクラス]{src/Unity/Vector3Cmd.cs} - -ソースコード\ref{src:RemoteMoveTest}、\ref{src:ObjectMoveCodeGear}、\ref{src:Vector3Cmd}は同一プロセスにおいて、 -RemoteDGMを使用しGameObjectの位置を操作するScriptである。 - -ソースコード\ref{src:RemoteMoveTest}のStartメソッドでは、playerCGMとenemyCGMの2つのDGMを用意し、 -playerCGMの方では他方のenemyCGMをRemoteDGMとして指定を行っている。 -また、enemyCGMではSetupを行い処理の待機状態にしている。 -Updateメソッドでは、このScriptが付与されたGameObjectの位置を取得し、x軸に+3、z軸に+3離れた位置にotherTransformを移動させるようにし、 -送信用クラスに変形を行っている。 -21行目ではotherTransformを持っているenemyCGMではなく、playerCGMからPutを行っている。 - -MessagePack CSharpではUnityにも対応しており、Unity APIが提供している値型のVector3やQuaternionなどもSerialize/Deserialize可能である。 -しかし、Christie SharpではDGでデータを管理する際に全ての型に対応できるようObject型にCastをしている。 -このObject型のCastが原因によりVector3型を直接送信することができない。 -そのため、ソースコード\ref{src:Vector3Cmd}のようにデータをプリミティブ型に分割してデータを送信している。 - -ソースコード\ref{src:ObjectMoveCodeGear}はソースコード\ref{src:PositionAssignCodeGear}と同様にMainThreadDispatcher.Postによって、 -処理はMain Threadに移譲されて実行される。 - - -\lstinputlisting[label=src:ObjectMoveServer, caption=GameObjectの位置をRemoteDGMに送信するScript]{src/Unity/ObjectMoveServer.cs} -\lstinputlisting[label=src:ObjectMoveListener, caption=GameObjectの位置を受信して位置を操作するScript]{src/Unity/ObjectMoveListener.cs} - - -ソースコード\ref{src:ObjectMoveServer}、\ref{src:ObjectMoveListener}は2台のPCを使用しLAN内でGameObjectの位置を通信して操作するScriptである。 -CGや、送信するDGについては、ソースコード\ref{src:ObjectMoveCodeGear}、\ref{src:Vector3Cmd}を流用している。 - - -ソースコード\ref{src:ObjectMoveServer}、\ref{src:ObjectMoveListener}それぞれの3行目ではhostNameを指定しており、通信先のLocal IPアドレスを入力することでSocket通信を行っている。 -ソースコード\ref{src:ObjectMoveServer}は位置データの送信元であり、RemoteDGMとして指定したlistenerに向けて、自身のGameObjectの位置をPutしている。 -ソースコード\ref{src:ObjectMoveListener}は何もデータをPutしておらず、LateUpdateメソッドでSetupを行うことでソースコード\ref{src:ObjectMoveServer}から受け取ったデータを基にGameObjectの位置を変更している。 - - -以上のテストにより、Chrisite Shrapの機能が問題なくUnity上でも機能することが確認できた。 - -\section{UnityでのChrisite Sharpの役割} -UnityでCodeGearを動作させる場合、特にUnity APIを使用して処理を行う際は、MainThreadDispatcher.Postメソッドを利用してMain Threadに処理を以上する必要がある。 -他方、UnityではUpdateメソッドやFixedUpdateメソッドなどUnityの実装に従って、フレーム単位や時間単位でのメソッド呼び出しが保証されている。 -CG内でMainThreadDispatcher.Postメソッドを使用しGameObjectの移動などのUnity APIを利用した処理を行うことで、処理が行われるタイミングが不安定になることがあると考えられる。 - -そこで、ネットワーク上で通信が必要なものだけをChrisite Sharpで通信を行い、受信データをMonoBehaviourを継承したクラスで処理・動作させるという方法を考えた。 -Unityには非同期処理としてCoroutineやTaskなどがあるが、シングルスレッドでの動作を前提として利用されている。 -この手法を取ることにより、Unity上の処理を行うタイミングが保証されると共に、 -並列処理やデータのやり取りをChristieに一任することができ、Multi Threadによる並列処理が可能となる。 - - -またUnity上で操作、処理を行っているGameObject自体をDGに継続にする、直接的にはDGにすることによってより並列処理などを意識することなくゲーム開発が可能となる。 -GameObject自体をDGにすることにより、通信に必要なデータを送信するためのコードを書かずに待ち合わせが可能となる。 -また、待ち合わせを行っていることによりデータがNullのまま処理を開始することがなくなる。 -位置などの毎フレーム必要なデータや、画面の描画に必要なデータはPeekで取得を行うことで、通信が途中で途切れてしまった場合でもその直前のデータは参照可能であり、 -接続の復帰も行いやすいと考えられる。
--- a/Paper/chapter/5-LibraryComparison.tex Thu Feb 10 10:16:06 2022 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -\chapter{Christie Sharpの評価} - -前章まではChristie Sharpの実装やUnity上での動作について述べた。 -本章では、Unityで使用可能な通信ライブラリであるPhoton Unity Networking2、MirrorとChristie Sharpの比較を行い、 -Unityで使用する場合のChristie Sharpの評価を行う。 - -\section{Christie Sharpと既存ライブラリの比較} - -既存の通信ライブラリとしては前述した、Photon Unity Network2とMirrorをChristie Sharpとの比較を行う。 -表\ref{tb:Libraryfeature}はChrisite Sharp、PUN2、Mirrorのそれぞれの特徴をまとめたものである。 - - -\begin{table}[htbp] - \begin{center} - \caption{各通信ライブラリの特徴} - \begin{tabular}{|c|c|c|c|} \hline %hlineで縦線 |c|で要素をくくる - & node間の通信方法 & Unity APIの対応 & 拡張可能か \\ \hline -Christie Sharp & p2p & 未対応 & 可能\\ \hline -PUN2 & Server Client & 対応 & 一部可能\\ \hline -Mirror & Server Client & 対応 & 可能\\ \hline - \end{tabular} - \label{tb:Libraryfeature} - \end{center} -\end{table} - - -PUN2やMirrorはnode間の通信方法としてクライアントサーバ方式を取っている。 -背景には、PUN2はPhoton Cloudを前提にServerへの接続が行われており、MirrorはMMOでの動作を前提に作成されているからである。 -一方Christie Sharpは、Topology Managerを利用して各nodeの接続を行っているためServerは無く、p2pでの接続となる。 - -Unity APIの対応に関しては、PUN2、MirrorがUnity APIで提供されている独自の型を簡単に同期できる機能があるが、 -Christie Sharpにはその機能が存在せず、データの同期にはC\#のプリミティブ型に変換して送信する必要がある。 - -拡張が可能かについては、Christie Sharp、Mirrorはユーザ自身が拡張可能である。 -Christie SharpはGitHubにて公開予定であり、MirrorはOSSなため、プロジェクトの状況に応じた機能の追加や変更などが可能となっている。 -一方PUN2はUnity上で動作するClient側のソースコードは公開されているが、Server側はPhoton Cloudを使用する必要があるため、拡張性は他の比較対象と比べ低い。 - - -PUN2ではPhoton Cloudがあるが、無料での使用には制限がかかり、制限を超えると別途Serverの料金が発生する。 -Mirrorは自前でServerを用意する必要があり、処理の大半はServerで行われるためServerのスペックを考えて開発する必要があある。 -Chrisite SharpはUnity APIへの対応が未対応が目立つ一方、p2pで通信を行うため、強力なServerを必要としない。 -またp2pの形式を取っているが、Topology ManagerのHostをServerで作動させることで、クライアントサーバ方式に変更することも可能である。 - - -\section{Christie Sharpの利点} -他の通信ライブラリと比較して、Chrisite Sharpを利用する利点として、以下が挙げられる。 - -\begin{itemize} - \item 単体でも並列処理が可能 - \item 通信切断した際にゲームロジックが停止しない -\end{itemize} - -他の通信ライブラリでは、並列処理の外部ライブラリを導入する際に、ライブラリ同士の相性や処理方法について考える必要がある。 -並列処理や非同期処理のDebugは複雑であり、複数のライブラリで問題が起きていた際に特定と解決は困難である。 -Chrisite Sharpでは、CodeGear/DataGearを使用した待ち合わせ処理を基本として処理が行われる。 -この処理はMulti Threadで行われているため、ユーザは並列処理や非同期処理を必要以上に意識せずにプログラムが可能である。 -並列処理のライブラリを導入しなくても済むため、問題の特定は複数のライブラリを組み合わせた場合と比べ容易になる。 - - -node間の通信において、通信の切断は必ず発生する。 -通信が切断された際に、ゲームロジックが破綻しゲーム全体が続行不可能になる場合もある。 - -通常、切断時にゲームロジックが停止しないような例外処理を行う必要があるが、Chrisite Sharpでは常に参照すべき値をPeekで取得することによって、 -通信が切断されても参照データは消えずに参照可能である。 -また、Topology ManagerにはCookieの機能が備わっているため、改良することによって通信が切断された場合にでもゲームに復帰することが可能になると考える。
--- a/Paper/chapter/conclusion.tex Thu Feb 10 10:16:06 2022 +0900 +++ b/Paper/chapter/conclusion.tex Thu Feb 10 10:50:37 2022 +0900 @@ -1,4 +1,7 @@ \chapter{まとめ} +本研究では、Christieの概要について説明を行い、Unityで使用可能な通信ライブラリの特徴を挙げた上で、ChristieをC\#に書き換える意義について述べた。 +またC\#での再実装時に発生した問題である、attributeの実装、CodeGearの処理をThreadからTaskへの変更、MessagePackのバージョン変更、 +MessagePackを使用する際の送信パケットの変更について述べた。 \section{今後の課題}