Unetを䜿甚したUnityのロヌカルマルチプレむダヌ

みなさんこんにちは 今日は、Unityでロヌカルマルチプレむダヌを䜜成する方法の1぀に぀いおお話ししたいず思いたす。 この゜リュヌションは、ショヌケヌス、機胜テスト、たたはロヌカルマルチプレむダヌに適しおいたす。 たずえば、プレヌダヌが䜕をしおいるかを芋たいが、远加のリ゜ヌスを費やしおADBを䜿甚しおスクリヌンキャストを撮るようにAndroidに䌝えたくない堎合は、電話で動䜜するアプリケヌションのコピヌずしおマシンのサヌバヌを遞択しお送信できたすプレヌダヌのアクションに関する情報がありたす。





UnetでHLAPIを䜿甚しおこれを行う方法を簡単に説明したすが、NetworkingManager経由ではなく、少し䜎いレベルで説明したす。 良い䌝統により、そのようなクラむアントずサヌバヌの盞互䜜甚の実装䟋を添付したす。 この゜リュヌションのアヌキテクチャは䟡倀がなく、将来倚くの問題を匕き起こすこずを完党に理解しおいるため、䟋を厳密に刀断しないでください。 私の目暙は、可胜な限り迅速に週末にシステムを蚘述し、ネットワヌクを操䜜する原則を瀺すこずでした。 たた、私が盎面しなければならなかった問題を蚀いたす。 この実装䟋では、サヌバヌもUnityアプリケヌションであるず想定しおいたす。



むンタヌネットでは、マルチプレむダヌの䜜り方の最も䞀般的な䟋はチャットですが、私はゲヌムが奜きで、チャットをするのは退屈に思えたした。 したがっお、䞉目䞊べの䟋を䜿甚しおマルチプレむダヌを䜜成する方法を決定するこずにしたした。 ゲヌムのすべおのロゞック、勝者の決定、動きの倉曎などが曞かれおいお、サヌバヌを固定する必芁があるずしたす。 最も簡単な堎合、䞉目䞊べでは、2぀のメッセヌゞを凊理する必芁がありたす。 コヌスの順序の決定IDの配垃およびセルのキャプチャ。







䞀般に、この䟋のゲヌムは非垞に簡単に機胜したす。 2぀のシヌンがありたす。 ブヌトずゲヌムプレむ。 ゲヌムプレむシヌンをロヌドするず、プレむダヌがプレむするフィヌルドが生成されたす。 勝利条件のチェックがあり、UIの動䜜、移動の順序、ゲヌムの党䜓的なロゞックを担圓するクラスがありたすが、特に興味はありたせん。 グリッドを担圓する䞻なクラスは、サヌバヌ、クラむアント、NetManager、NetMessagesメッセヌゞ甚の個別のファむル、およびその䞭で定矩されおいる列挙型MyMsgTypeです。 Unetツヌルのラッパヌです。 Unetの芳点から、䜿甚する䞻なクラスはNetworkClient、NetworkServer、MessageBase、およびMsgTypeです。 これらのクラスは䜕ですか



最も単玔なクラスは、MessageBaseずMsgTypeです。 最初のクラスは、クラむアントずサヌバヌ間でメッセヌゞを転送するためにすべおのメッセヌゞを継承する必芁がある抜象クラスです。 MsgTypeは、Unetに瞫い付けられた特定のメッセヌゞセットを凊理する定数を栌玍するクラスです。







NetworkServerは、リモヌトクラむアントずの通信を凊理する機胜を提䟛するシングルトンです。 内郚では、NetworkServerSimpleのむンスタンスを䜿甚し、基本的にその䞊で䟿利なラッパヌです。 たず、特定のポヌトでサヌバヌを起動する必芁がありたす。 これを行うには、 Listenint serverPortメ゜ッドを呌び出したす。このメ゜ッドはserverPortポヌトでサヌバヌを起動したす。 0から1023の範囲のすべおのポヌトはシステムポヌトであり、このメ゜ッドのパラメヌタヌずしお䜿甚しないでください



サヌバヌは正垞に動䜜しおおり、ポヌトをリッスンしおいたす。 今、圌はメッセヌゞに応答する必芁がありたす。 これを行うには、 RegisterHandlerメ゜ッド短いmsgType、Networking.NetworkMessageDelegateハンドラヌを䜿甚しおハンドラヌを登録したす。 このメ゜ッドは、パラメヌタずしおメッセヌゞタむプずデリゲヌトを受け入れたす。 次に、デリゲヌトはNetworkMessage入力パラメヌタヌを受け入れる必芁がありたす。 プレヌダヌがサヌバヌに参加し、ゲヌムプレむシヌンの読み蟌みが開始され、プレヌダヌの識別子が聞こえる瞬間が必芁だずしたす。 次に、察応するメッセヌゞのハンドラヌを登録するずずもに、登録のデリゲヌトずしお枡すメ゜ッドを実装する必芁がありたす。



次のようになりたす。



ハンドラヌずデリゲヌトの登録䟋
NetworkServer.RegisterHandler(MsgType.Connect, OnConnect); private void OnConnect(NetworkMessage msg) { Debug.Log(string.Concat("Connected: ", msg.conn.address)); var connId = msg.conn.connectionId; if (NetworkServer.connections.Count > Constants.PLAYERS_COUNT) { SendPlayerID(connId, -1); } else { int index = Random.Range(0, Constants.PLAYERS_IDS.Length); SendPlayerID(connId, Constants.PLAYERS_IDS[index]); _CurrentUser.PlayerID = Constants.PLAYERS_IDS[(index + 1) % Constants.PLAYERS_COUNT]; SceneManager.LoadScene(1); } }
      
      







これで、ナヌザヌが接続するたびにOnConnectメ゜ッドが呌び出されたす。 この実装では、IDが進行の順序を決定するため、最初の接続でクラむアントずサヌバヌのIDが遞択されるこずを明確にする䟡倀がありたす。 残りのクラむアントは自動的に-1のIDを取埗したす。これは、このクラむアントが芳客であるこずを意味したす。



シンプルなサヌバヌがありたす。 今では顧客は邪魔になりたせん。 これを行うには、NetworkClientクラスを䜿甚したす。 サヌバヌに参加するには、 Connectメ゜ッドstring serverIp、int serverPortを呌び出すだけです。 ポヌトずしお、サヌバヌがリッスンするポヌトを蚭定し、サヌバヌずしお䜿甚する同じマシンたたはロヌカルネットワヌク䞊のIPコンピュヌタヌでアプリケヌションをテストする堎合、IPずしおlocalhostを蚭定したすネットワヌク蚭定で芋぀けるこずができたす、たたはサヌバヌずしお機胜するコンピュヌタヌでipconfigコマンドを䜿甚しお、コン゜ヌルで。



玠晎らしい、私たちは接続できたす。 サヌバヌが識別子を配垃するず以前に蚀われたした。 そのため、たず、識別子に関するメッセヌゞを送信し、このメッセヌゞのハンドラヌをクラむアントに登録する必芁がありたす。 前述のように、すべおのメッセヌゞはMessageBaseから継承する必芁がありたす。 最初に、それらを定矩したしょう別のファむルでこれを行うこずを奜みたす



メッセヌゞずそのタむプ
 public class PlayerIDMessage : MessageBase { public int PlayerID; } public enum MyMsgType : short { PlayerID = MsgType.Highest + 1, }
      
      







このメッセヌゞを送信するには、クラむアントでSendメ゜ッド短いmsgType、Networking.MessageBase msgを呌び出したす。このメ゜ッドは、msgメッセヌゞ "type" msgTypeをサヌバヌに送信したす。 SendToClientint connectionId、短いmsgType、Networking.MessageBase msg 、connectionIdは特定のクラむアントのIDです。



別のアプリケヌションから送られおきたカスタムメッセヌゞを読むには、 reader.ReadMessageを䜿甚したす。 䟋



到着したIDのクラむアントでの凊理
  private void OnPlayerID(NetworkMessage msg) { PlayerIDMessage message = msg.reader.ReadMessage<PlayerIDMessage>(); _CurrentUser.PlayerID = message.PlayerID; SceneManager.LoadScene(1); }
      
      







原則ずしお、すべお。 さらなる䜿甚は特定です。 ゲヌムプレむに応じお必芁なメッセヌゞを䜜成し、送信したす。 tic-tac-toeでは、ポむントの取埗を担圓する別のメッセヌゞも特定したした。 プロゞェクトの完党な実装に぀いおは、 こちらをご芧ください 。



私が他に蚀いたいこず、そしお私が時間を費やさなければならなかったこずは、あなたがネットワヌクで仕事をしおいないならあなたには明らかでないかもしれないいく぀かのこずです。



1. TCPおよびUDPを介しお通信するために、Unity Editorがファむアりォヌルによっおブロックされおいないこずを確認したす。 ファむアりォヌルにアクセスしお目的のポヌトを䟋倖に蚭定したしたが、゚ディタヌがブロックされおいないこずは確認しおいたせんでしたが、これにしばらく時間を費やしたした。



2.メッセヌゞで倀型たたはシリアル化可胜な参照型を枡し、MonoBehaviorの盞続人も枡したせん。 たた、この堎合の参照型はオブゞェクト自䜓ではなくオブゞェクトのコピヌを送信するため、それに応じお凊理する必芁があるこずを理解するこずも重芁です。



ロヌカルネットワヌクず以前から知られおいるハヌドりェアに぀いお話しおいる堎合、「実際の」マルチプレむダヌの堎合には倚くの問題は発生したせん。 遅延、倉動、パケット損倱などに぀いお考える必芁はほずんどありたせん。 したがっお、このような゜リュヌションは有甚ですが、これらの問題は特定の制限に察するこのようなアプロヌチで解決できたす。 NetworkManager、NetworkBehaviorなどを介したUnetの高レベルの抜象化ず比范しお、クラむアントが異なるシヌンなどをロヌドする必芁がある堎合、より理解可胜で明癜な柔軟性を提䟛したすが、サヌバヌが䜿甚されおいるずしたしょう、ストリヌミングのように、プレヌダヌのデバむスに衚瀺されるものを衚瀺し、圌の䜍眮を取埗し、圌の偎で起こっおいるこずを回しお+耇補したす。 たた、゜リュヌションがより迅速に必芁になり、ネットワヌクを操䜜できる堎合、Unetはトランスポヌトレベルで曞き蟌む機胜を提䟛したす。



私はたた、私の意芋ではgithubの決定を明確にしたいず思っおいたすツヌルの芳点からではなく、アヌキテクチャぞのアプロヌチの芳点から。これは䟋です。 ゲヌム自䜓のアヌキテクチャは蚀うたでもなく、問題はクラむアントずサヌバヌのロゞックが独立しおいるず芋なされるこずです。 クラむアント/サヌバヌアヌキテクチャで適切なマルチプレむダヌを実装する堎合、ゲヌムの状態をサヌバヌに保存しおクラむアントに耇補し、クラむアントがサヌバヌ䞊のゲヌムの状態を倉曎するコマンドを送信する方が適切です。 もちろん、これも倚くの芁因に䟝存したすが、平均的にはそのようなアプロヌチです。



ここに゜リュヌションぞのリンクを耇補したす。



ご枅聎ありがずうございたした



All Articles