アマゾンバナーリンク

所有権を制する者はオンラインゲームを制する

こんにちは!ジェイです。最近ずっと自作TPSオンラインゲームのUnityChanShooterを作っていました。沢山のバグを修正することになるのですが、オフラインゲームにはなく、オンラインゲームならではのバグの特性について説明します。

所有権を理解しなければオンラインゲームは作れない

所有権をまったく気にせずオフラインゲームと同じコードを書くと下の様な状況になります。

Image from Gyazo

単純に理由を言えば、「全員のプレイヤーキャラクタを、プレイヤー全員で動かそうとしているから」です。

例えば、オフラインゲームを開発していて、「上を押したら前進する」という処理をプレイヤーキャラクタに適用させるとします。それが「オフラインゲーム」のままであれば、そのまま実行すれば動きます。

しかし「オンラインゲームに移行する」のであれば、自分のプレイヤーキャラクタも、相手のプレイヤーキャラクタも、誰かが「上を押したら前進」します。結果、ネットワーク上の全ての「プレイヤーキャラクタ」が、各々のクライアントにより「同じ動き」をするようになってしまうのです。

所有権とはオブジェクトを動かす権利

PhotonCloudやMonobitEngineはPhotonNetwork.player.id(PUN)やPhotonNetwork.LocalPlayer.UserId;(PUN2)やMonobitEngine.MonobitNetwork.player.IDなどで参照できるPlayerIDというものが存在します。

これはネットワーク上にアクセスしているプレイヤー1人に1つだけ割り当てられるIDです。ルームに入室する度に毎回変わりますが、必ず他のプレイヤーと被ることがないユニークな値が入ってます。これはPhotonViewやMonobitViewを見ると確認できます。

これを見るとplayerIDが1のplayer61262という名前のプレイヤーがこのオブジェクトを操作する権利を持っています。スクリプトの中で判断するには、photonview.isMineやmonobitView.isMineを使います。trueが返ってきた時には、このIDを持つ所有者ということになります。

所有権がわからない事によって起きたバグ

これを理解しないで書くと下のような事が起きます。

特に乗り物など、車の所有権を動かす人に譲らないと、この様に所有権がない人が中に取り残されてしまうと動かないという現象が起きます。

MonobitView1つ1つに必ず所有権が設定されてる理由

2020/11/14にYouTube配信で武器を持った人がそのまま退室し、その人や他の人がルームに再入場するとすでに破棄されたはずのオブジェクトが破棄されたとホストにエラーが出る現象に悩まされましたが、結局はこれも所有権の問題でした。以下がその時の配信です。

さて、このエラーですが車で所有権の問題を意識することになっていたので、原因はすぐに理解して、所有権を持つキャラクターが所有権を持たない武器を持ったままルームを退室するというのが問題だと気づくことができました。それをふまえたうえで解決方法は以下の2つが思い浮かびました。

  • 落ちる前にOnLeftRoomなどのコールバックで武器を捨てる
  • 武器を拾う時に所有権を拾った本人に移譲する

1つ目は試してみましたが、すでに部屋から出た後によばれるので、武器を捨てる処理が間に合いません。ということで、見事に2つ目の方法を実行してみたところ再入場してもエラーがでなくなりました。

実際のコードは以下のたった1行です。それと事前にMonobitViewのRequestをTakeOverにする必要があります。

monobitView.TransferOwnership(MonobitEngine.MonobitNetwork.player.ID);

結論 キャラや物は誰が所有して動かしていいのかを意識する事が大事

今回のバグはリスナーのみなさん1人1人が知恵を出し合いながら考えて、行動したおかげでかなり複雑なバグにも関わらずなおすことができました。正直1人では絶対見つけられなかったです。

キャラクターを操作するのは自分だというのは、普段から意識しますが、その動かすキャラクターが持っている武器や車などにも所有権があります。

所有権のない人がアクセスしたら、車の場合はスクリプトを書いても動きませんが、今回のように武器の場合は装備して見た目だけ扱う場合があるので、自分が所有権のない武器をキャラが持っている可能性があってこれは深刻なバグを起こす原因にもなります。

これはどのネットワークエンジンでも必ず必要な知識になるので、これからオンラインゲームを制作しようと思う人は、所有権について理解しましょう!