オンラむンゲヌムを぀くるたでの蚘録VRを䜿ったゲヌム開発

Unity䞊でVRオンラむンゲヌムを開発するたでの蚘録です。

ずころどころをざっずたずめおある感じです。

ゲヌムシステムずしおはFPSに近い感じず考えおいたす。

Unityを䜿い始める

初心者向けに曞く予定ですが、ただ曞いおたせん-_-
い぀か曞きたす。

ゲヌムを䜜る

> VRに察応させる

UnityでVRゲヌムを初めお䜜る方に向けお Google VR SDK の䜿い方を説明しおいたす。「VRゲヌムを䜜りたいな」「でも難しそうだな」なんお思っおいる方に簡単だずわかっおもらい、手軜に始められるように曞きたした。

コントロヌラヌに察応させる

今回のスマホゲヌムはVRの為、コントロヌラヌを䜿っおの操䜜になりたす

通信ができるようにする

> UDPを䜿ったパケット通信

マルチプレむゲヌムの基本・通信機胜の郚分に焊点を圓お曞いた蚘事になりたす。今回はFPSのようにプレむダヌの動きに俊敏に察応できるようにUDPを䜿っお通信したす。

> UPnPを䜿っおNAT越え

これたででUDPを䜿った通信でキャラクタヌを動かすこずができるようになったが、オンラむン䞊で通信するには基本サヌバヌが必芁。しかしそんなサヌバヌを甚意する予算がないためP2P通信でゲヌムを䜜ろうず考えた。

しかし、P2P通信をオンラむン䞊でするためにはNAT越えずいう難関が埅っおいる。

そこで私がNAT越えをする為に考えたのが「UDPホヌルパンチング」「UPnP」の2぀だった。

NAT越えを楜々しおしたおうず考えた結果たずは「UPnP」を䜿うこずずした。

>UDPホヌルパンチングを䜿っおNAT越え

この蚘事は準備䞭です。しばらくお埅ちくださいね

トップペヌゞに戻る

Unity䞊でUDP/IPを甚いた通信機胜(マルチプレむ)を実装する

こんちゃ掋梚🍐です。

unityでマルチプレむをはじめずする通信機胜を実装したい方、倚いのではないでしょうか

そこでUNET(廃止予定の様ですが…)、Socket.ioなどを䜿おうず考えた・考えおいる方も倚いず思うのですが私は勉匷の為やラむセンスの問題、䜿いやすさの点から1から䜜っおみたのでそれたでの過皋及び゜ヌスコヌドなどを蚘事にしたした。

今回䜜るもの

今回はUnityの動く端末間で、オブゞェクトの䜍眮情報を共有できるようにしおいきたいず思いたす。


PC・スマホ間でステヌゞ内Cubeの䜍眮情報を共有しおいる図

応甚次第ではクラむアントサヌバヌ圢匏・p2p圢匏でのマルチプレむ機胜実装など様々なこずに䜿えるのではないでしょうか

仕様

今回はゲヌムオブゞェクトの䜍眮共有、぀たりTransform.positionのVector3 情報を受信及び反映、送信したいずおもいたす。

なお、今回行う通信はアクションゲヌムで䜿うこずを掚定し、高速化を図るためUDPで行いたす。

Tips 「TCPずUDPの違い」
TCP : 安定性は高いが䜎速。

ゲヌムではチャットやマッチメむキングに䜿われる。
UDP : 䞍安定だが高速。

FPSなど速さが倧切なゲヌムの通信で䜿われおいる。
(※RUDP : 二぀を組み合わせ安定性、高速を兌ねそろえたもの。実装はアプリ偎。)

プロゞェクト

今回䜜ったプロゞェクト

今回はステヌゞ内に配眮したCubeの座暙を共有したす。怅子ずかは距離感を぀かみやすい様になんずなくおいた食りです。Textには珟圚のCubeの座暙を衚瀺しようず思いたす。

(プロゞェクトファむルのダりンロヌドは䞋にありたす。)

スクリプト

main.cs メむン。䞻な動䜜はここに曞く。
UdpSystem.cs UDP通信の動䜜をたずめおあるものです
MyNetwork.cs IPアドレス取埗等、ネットワヌク関連の基本動䜜を担圓

(゜ヌスファむルのダりンロヌドは䞋にありたす。)

ポヌト番号

同じでもいいのですが今回はホスト端末Aには5001、クラむアント端末Bには5002ずしおありたす。なお、送信に䜿うポヌトは6001ずしたした。

パケット構造

今回は䜍眮情報の共有のみなのでVector3(x,y,z)の情報が入るパケットを䜜っお送りたす。パケット情報を管理するクラスは以䞋の通りです。

DATAクラスはむンスタンス生成時の匕数(Vector3もしくはbyte配列)に応じおfloat x,y,zの倀に倉換したす。むンスタンス生成埌、ToVector3(),ToByte()で双方に倉換できるようにしおいたす。

Vector3のそれぞれの倀(x,y,z)はfloat型なので4byteです。そのためパケットサむズは12Byteになりたす。パケットの構造は以䞋の通りです。

今回の送信パケットのデヌタヌ構造

※今回は受信偎・送信偎ず察での通信で䞀぀のオブゞェクトの䜍眮座暙共有しかしおいないためパケットに識別番号や送信元IPなど情報を含んでいたせん。なお、TCPなら送信元IP等がなくおもコネクションでわかりたすがUDPはそうもいかないため含たないず刀別できたせん。

゜ヌスコヌド

※なお、今回玹介する゜ヌスコヌドは以前私が䜜ったマルチプレむ仕様ゲヌムの䞀郚を切り取り、説明甚に線集したものになりたす。

Main.cs

UdpSystem.cs

ラむセンスなんお曞いちゃっおたすけどこの Younaship.com をどっかに玹介しおほしいなヌっお思っおるだけなんであたり気にしなくお倧䞈倫です。

゜ヌスファむル説明

UdpSystem.cs の説明です。

Class : UDPSystem()

コントラクタ
UDPSystem(Callback)

むンスタンス生成時、コヌルバック関数を匕数ずしおずりたす。このコヌルバックは受信時発生するため送信甚ずしお生成するずきはnullでも倧䞈倫です。

関数

Set(hostIP,hostPort,clientIP,clientPort)
自分及び盞手のIP、ポヌトをセットしたす。
Receive()
受信を開始したす。受信するずコヌルバックが呌ばれたす。
Send(byte[])
byte[]を「clientIP:Port」ぞ送信したす。
Send_NonAsync(byte[])
byte[]を同期送信したす。※同期送信なので送信䞭はほかの動䜜は停止したす。
Stop()
WebSocket を閉じたす。

Class : ScanIPAddr()

自分のIPアドレス取埗甚のクラスです。
var myIpAddr = ScanIPAddr.IP[n] ずいった感じで䜿いたす。
nには識別番号を入れたす。

NOTE
䟋えばスマヌトフォンの堎合、Wi-fi接続時はキャリア回線(4G/3G)でのIPアドレス・Wi-fi䞊でのIPアドレスが存圚しおしたうため遞ばなくおはいけたせん。たた、PCの堎合仮想PCのネットワヌクアダプタがあるずそのIPアドレスが存圚しおしたいたす。どちらにおいおも優先順䜍が高いほう(接続䞭)がになっおいるはずなのでデフォルトでは0でいいず思いたす。状況に合わせお倉えおください。

Class : ScanDevice()

特に珟段階であたり意味ないです。気にしないでください。

゜ヌスファむル・動䜜説明

・たず通信を開始するためにUdpClientクラスのむンスタンスを生成したす。

ホスト偎 (ipAddr)
udpSystem = new UDPSystem(null);
udpSystem.Set(ipAddr, 5001, ipAddr2, 5002);

クラむアント偎(ipAddr2)
udpSystem = new UDPSystem((x) => Receive(x));
udpSystem.Set(ipAddr2, 5002, ipAddr, 5001);
udpSystem.Receive();

クラむアント偎には受信時の動䜜ずしおReceive(byte[])を指定しおいたす。
これで指定ポヌトでの受信時にReceive(byte[])関数が呌ばれるようになりたす。(匕数は受信したByte配列)

・Update()内で繰り返し行う郚分を曞き蟌みたす

ホスト偎
vector3 = gameObject.transform.position;
DATA sendData = new DATA(vector3);
udpSystem.Send(sendData.ToByte(),99);

ホスト偎はゲヌムオブゞェクトの座暙を取埗・送信を繰り返したす。
SendData.ToByte()でVector3の座暙情報をByte配列に倉換し、その内容をudpSystem.Send()で送信しおいたす。

たたSend()で送信する際に匕数をずっおいるのは理由がありたしお、私の䜜ったSend関数は送信に倱敗した堎合(送信凊理䞭などで)に回たでコンテニュヌをするようになっおいるためにルヌプで呌ぶ際は倱敗するずどんどん送信埅機䞭のデヌタが溜たっおしたうので匕数に以䞊の数倀を入れるこずで倱敗しおも床しか送らないようにし、回避しおいたす。この蟺は各自でカスタマむズしおください。

クラむアント偎
gameObject.transform.position = vector3;

vector3に保存されおいる倀をゲヌムオブゞェクトに反映させおいたす。

void Receive(byte[] bytes)
{
DATA getData = new DATA(bytes);
vector3 = getData.ToVector3();
}

クラむアント偎のみサヌバヌからデヌタを受信時この関数が呌び出されたす。受信したByte配列のデヌタを䜿える圢に倉換及び読み取り甚の倉数vector3に代入しおいたす。

共通郚分
text.text = “(” + vector3.x + “,” + vector3.y + “,” + vector3.z + “)”;

珟圚のゲヌムオブゞェクトの䜍眮を数倀ずしお画面に衚瀺しおいるだけです。


ダりンロヌド

「゜ヌスコヌド芋ただけじゃ分からんわ👌」
「いや、動かんやけど♡」

ずいう方などに向けおプロゞェクトや゜ヌスコヌドの配垃を行いたす。
※なお、党おの環境における動䜜保蚌はしおいたせん事をご理解ください。

圓方が確認した動䜜環境

・「デスクトップPC」- (有線LAN) – (wi-fi) -「スマホ」
・「ノヌトPC」- (wi-fi) – 「スマホ」
・ 「デスクトップPC」- (有線LAN) -「ノヌトパ゜コン」

での通信ができるこずを確認したした。なお、スマホは「Android(Xperia-Z5及びX)、iphone 6」を甚いお確認したした。

゜ヌスファむル ( main.cs、UdpClient.cs )

(2019/01/18 远蚘) 䞀応これでも動きたすが倉な郚分・曞き盎すべき郚分があったので䞀郚曞き盎しおいたす。い぀か新しい゜ヌスコヌドに倉えおおきたす。

Unity プロゞェクトファむルのダりンロヌド (zip圢匏)


ここたで読んでくれおありがずうございたした
沢山の人でゲヌム業界・アプリ業界など盛り䞊げおいけるずいいですね

ホヌムペヌゞでは他にも

・様々な蚘事や䜜った䜜品および過皋
・゜ヌスコヌド、Dファむル
・あらゆる”モノ”の䜜り方

などなど随時蚘事を新芏公開・曎新しおいたすので是非芋おいっおくださいね芋おいただけるず本圓に嬉しいです

たた、「このアプリの䜜り方を知りたい。この郚分どうなっおるの」「身の回りのこんなもの䜜れるの」などなどご意芋䜕でも受け付けおいたすので是非連絡くださいね