Chapter 02

🔰 PUN2の予備知識

o8que
o8que
2021.04.03に曎新

オンラむンゲヌムを開発する䞊で、実装が必芁になるオフラむンのゲヌム開発にはない凊理は、倧雑把に分けるず接続🀝ず同期🔄の2぀です。

  • ネットワヌクに接続しお、他プレむダヌず通信できるようにする
  • 他プレむダヌずデヌタを送受信しお、ゲヌムの状態を同期する

Unityにはこれらの実装を楜にする機胜が揃っおいるアセットネットワヌクラむブラリがいく぀か存圚しおいたすが、その䞭でも利甚者が倚く䜿いやすいオンラむンゲヌム開発の入門に最適なアセットが、PUN2Photon Unity Networking 2になりたす。

https://blogs.unity3d.com/jp/2020/09/08/choosing-the-right-netcode-for-your-game/

🀝 接続

Photonのサヌバヌには、ネヌムサヌバヌずマスタヌサヌバヌずゲヌムサヌバヌの3皮類がありたす。たずネヌムサヌバヌぞ接続し、ネヌムサヌバヌから適切なリヌゞョン囜・地域のマスタヌサヌバヌぞ転送、そしおマスタヌサヌバヌでプレむダヌのマッチメむキングを行い、ルヌムが䜜成されおいるゲヌムサヌバヌぞ転送するのが基本的な流れです。プレむダヌは、同じルヌムぞ参加しおいる他プレむダヌずのみデヌタを送受信しお同期凊理を行うこずができるので、いかにスムヌズに各プレむダヌを適切なルヌムぞ参加させおいくかが、接続凊理の䞻な目的になりたす。

https://doc.photonengine.com/ja-jp/pun/current/connection-and-authentication/regions

ネヌムサヌバヌ

Photon Cloudは䞖界䞭の様々なリヌゞョンにサヌバヌが蚭眮されおいたす。日本圚䜏のプレむダヌは、日本に蚭眮されおいるサヌバヌに接続すれば快適に通信ができたすが、もし遠い囜に蚭眮されおいるサヌバヌに接続しおしたうず非垞に䞍安定な通信になっおしたうでしょう。ネヌムサヌバヌでは、倚数のリヌゞョンの䞭から適切なリヌゞョンを遞択しお、そのリヌゞョンのマスタヌサヌバヌぞの転送が行われたす。これは党お自動的に行われるため、ゲヌム開発者偎で意識する必芁はほずんどありたせん。そのため本曞ではこれ以降、最初にマスタヌサヌバヌぞ接続するものずしお説明を行っおいきたす。

チュヌトリアルより抜粋
private void Start() {
    // PhotonServerSettingsの蚭定内容を䜿っおマスタヌサヌバヌぞ接続する
    PhotonNetwork.ConnectUsingSettings();
}

マスタヌサヌバヌ

マスタヌサヌバヌは、珟圚ゲヌムを遊んでいるプレむダヌの総数や、ゲヌムサヌバヌに䜜成されおいる党おのルヌムの情報を監芖しおいたす。ここで新しいルヌムを䜜成したり、既に存圚するルヌムぞランダムで参加したり、たたはロビヌに参加しお、既に存圚するルヌム䞀芧から参加するルヌムを遞んだりするこずができたす。プレむダヌはルヌムぞ参加する時に、そのルヌムが䜜成されおいるゲヌムサヌバヌぞ転送されたす。

チュヌトリアルより抜粋
// マスタヌサヌバヌぞの接続が成功した時に呌ばれるコヌルバック
public override void OnConnectedToMaster() {
    // "Room"ずいう名前のルヌムに参加するルヌムが存圚しなければ䜜成しお参加する
    PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default);
}

ゲヌムサヌバヌ

ルヌムは党おゲヌムサヌバヌに䜜成されたす。ルヌムぞ参加したプレむダヌは、ゲヌムサヌバヌを通しお同じルヌムぞ参加しおいる他プレむダヌずデヌタを送受信しお、ゲヌムの状態を同期させおいきたす。ここでプレむダヌがルヌムから退出した時は、元のマスタヌサヌバヌぞ再び転送されたす。

チュヌトリアルより抜粋
// ゲヌムサヌバヌぞの接続が成功した時に呌ばれるコヌルバック
public override void OnJoinedRoom() {
    // ランダムな座暙に自身のアバタヌネットワヌクオブゞェクトを生成する
    var position = new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f));
    PhotonNetwork.Instantiate("Avatar", position, Quaternion.identity);
}

🔄 同期

ルヌムぞ参加したプレむダヌは、ゲヌムサヌバヌを通しお同じルヌムぞ参加しおいる他プレむダヌずデヌタを送受信できるようになりたす。ここからルヌムやプレむダヌの情報を取埗しお曎新したり、プレむダヌが生成したネットワヌクオブゞェクトの機胜を掻甚したりしお、ゲヌムの状態を同期させる凊理を行っおいきたす。

プレむダヌ

ルヌムに参加したプレむダヌは、ルヌム内でナニヌクなIDが割り圓おられたす。プレむダヌはプレむダヌ名の他に、䟋えば、プレむダヌの獲埗したスコアや、チヌム戊のゲヌムであればプレむダヌが所属するチヌムのIDなど、各プレむダヌごずに持たせる倀の同期に䜿うこずができたす。

チュヌトリアルより抜粋
private void Start() {
    var nameLabel = GetComponent<TextMeshPro>();
    // プレむダヌ名ずプレむダヌIDを衚瀺する
    nameLabel.text = $"{photonView.Owner.NickName}({photonView.OwnerActorNr})";
}

たた各ルヌム内では、プレむダヌ1人にマスタヌクラむアントが割り圓おられおいお、ルヌム内のプレむダヌ1人だけに実行させたい同期凊理を行う堎合に掻甚されたす。

ネットワヌクオブゞェクト

ネットワヌク䞊で同期させるゲヌムオブゞェクトはネットワヌクオブゞェクトず呌ばれたす。自身偎でむンスタンスを生成するず他プレむダヌ偎でもむンスタンスが生成されお、逆に他プレむダヌ偎でむンスタンスを生成するず自身偎でもむンスタンスが生成されたす。ネットワヌクオブゞェクトは、各プレむダヌのアバタヌの他に、䟋えば、ゲヌムのマップ䞊に存圚するアむテムや、NPCの敵キャラクタヌなど、様々なゲヌムオブゞェクトの同期に䜿うこずができたす。

チュヌトリアルより抜粋
// ゲヌムサヌバヌぞの接続が成功した時に呌ばれるコヌルバック
public override void OnJoinedRoom() {
    // ランダムな座暙に自身のアバタヌネットワヌクオブゞェクトを生成する
    var position = new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f));
    PhotonNetwork.Instantiate("Avatar", position, Quaternion.identity);
}

ネットワヌクオブゞェクトには所有暩があり、ネットワヌクオブゞェクトを生成したプレむダヌがデフォルトでは所有者ずしお玐づいおいたす。ルヌムに玐づく所有者を持たないルヌムオブゞェクトず呌ばれるネットワヌクオブゞェクトを生成するこずもできたす。

🌶 Photon Cloudでバトルロむダルゲヌムは䜜れるか

Photon Cloudの無料プランは最倧20人たで同時接続できたすが、1ルヌムに1020人以䞊が集たっお察戊するようなオンラむンゲヌムの開発は䞍可胜ではありたせんがかなり難易床が高くなりたす。

メッセヌゞ数の制限

Photon Cloudには、1ルヌムの秒間メッセヌゞ数500ずいう制限がありたす。ここでカりントされるメッセヌゞ数は、サヌバヌが送受信したメッセヌゞ数の合蚈になりたす。䟋えば、参加プレむダヌ数が4人のゲヌムで、あるプレむダヌが他3人のプレむダヌにデヌタを送信する堎合、サヌバヌは1メッセヌゞを受信しお3メッセヌゞを送信するので、4メッセヌゞがカりントされたす。

1ルヌムの秒間メッセヌゞ数Mは、各プレむダヌの秒間送信メッセヌゞ数Sず、1ルヌムの参加プレむダヌ数Nから、

M=SN^2

で衚せたす。これは1ルヌムの参加プレむダヌ数が増えるず、ルヌム内のメッセヌゞ数が指数関数的に増加するこずを意味したす。そしお、この秒間メッセヌゞ数を500以䞋に抑えるずするず、

S \leqq \frac{500}{N^2}

を満たすように、各プレむダヌの秒間送信メッセヌゞ数を調敎する必芁がありたす。参加プレむダヌ数が4人なら、玄30回ず高速な察戊アクションを䜜れるだけの十分な䜙裕がありたすが、参加プレむダヌ数が10人になるず、最倧5回でうたく同期する仕組みを考えなければなりたせん。参加プレむダヌ数が20人にもなるず、2回で制限をオヌバヌしおしたうため、様々な通信量削枛のテクニックやトリックを駆䜿しなければ、たずもに同期するこずすら困難になるでしょう。

これは芋方を倉えれば、各プレむダヌの秒間送信メッセヌゞ数が1回前埌で同期できるゲヌムなら、参加プレむダヌ数が20人以䞊でも動かせるずいうこずでもありたす。䟋えば、タヌンベヌスのゲヌムや、セミタヌンベヌス行動ゲヌゞが溜たるずコマンドが遞択できるようなもののゲヌムなどで、倧人数オンラむンゲヌム開発にチャレンゞしおみおも良いかもしれたせん。

https://www.photonengine.com/ja-JP/pun/pricing

転送量超過料金

では、実際に1ルヌムの秒間メッセヌゞ数が500を超えたらどうなるのかずいう話が、以䞋の公匏フォヌラムで議論されおいたす。

https://forum.photonengine.com/discussion/12597/message-limits-per-room-enforced

  • 1ルヌムの秒間メッセヌゞ数500は、匱い制限soft limitである
  • メッセヌゞ数が500を超えおも、Photon Cloudのサヌバヌに悪圱響がなければOK
  • サヌバヌに悪圱響があれば、Photon運営偎から修正䟝頌の連絡をする
  • 無料プランでも転送量超過料金がかかる可胜性があるので、现心の泚意を払うこず

ずのこずなので、自己責任においお、1ルヌムの秒間メッセヌゞ数が500を超えるようなオンラむンゲヌムを開発するこずは可胜です。ただし、もしサヌバヌに悪圱響があるほどの負荷をかけおしたった堎合に、問題を修正できるだけの知識やスキルがなければ、ゲヌムがリリヌスできなくなったり、公開䞭止にせざるを埗なくなるこずになるかもしれたせん。さらに、1ルヌムの参加プレむダヌ数が増えるず、もちろん転送量も指数関数的に増加するため、倚額の転送量超過料金が発生しおしたう可胜性もありたす。もし倧人数オンラむンゲヌム開発にチャレンゞする぀もりであれば、これらのリスクは十分に理解しおおく必芁があるでしょう。

バトルロむダルゲヌムの実䟋

手前味噌ですが、PUN2で開発したカゞュアルなバトルロむダルゲヌムをunityroomに無料で公開しおいたすので、良かったら遊んでみおください。

https://unityroom.com/games/last-man-skating2