アマゾンバナーリンク

ディスプレイ広告

スポンサーリンク

PhotonPUN2のPhotonViewの設定についての解説

2021年3月29日

こんにちは!ジェイです。今回はPhotonPUN2で必須のコンポーネントであるPhotonView,PhotonTransformView,PhotonAnimatorViewの3つについて解説します。

記事内広告

PhotonView

Ownership

  • Fixed : GameObjectのクリエイターがオーナーであり続けます
  • Takeover : どのクライアントも現在のオーナーからGameObjectを取得できます
  • Request : 現在のオーナーにオーナーシップの移行をリクエストします。このリクエストは拒否することが可能です

Syncronization

  • Off : 同期は行われません。RPCを使用したい時だけに最適です
  • Unreliable : キャラクターが動いていない場合でも決まった頻度でアップデートを送信します
  • Unreliable On Change : GameObject (キャラクターやユニット)が止まっているときにはアップデートを送信しません
  • Reliable delta compressed : 最後の状態と現在の状態の差が送信され、変更が無い場合は何も送信されません

PhotonTransformViewClassic

Synchronize Position

  • Enable teleport for greater distances : 同期ズレが起きてオブジェクトの位置が大幅にズレた時に、オブジェクトをワープさせて補正するかどうかの設定です。ONにすると指定距離以上離れた時にオブジェクトの座標が強制的に上書きされます。アクションゲームなど、相手の現在位置が重要なゲームではONにした方が良いです。
  • Interpolate Option : 補間処理。設定することでオブジェクトの動きが滑らかに同期されるようになります。Disable : 補間を使わない設定で、動きがカクカクするのでおすすめしません
  • Fixed Speed : 常に一定速度でオブジェクトを追従させて補間します。同期対象のオブジェクトの速度が固定されている時に有効。
  • Estimated Speed : 受け取った「直前の座標」と「現在の座標」の差分を現在の速度と仮定してオブジェクトを移動させて補間します。ゆっくりと加速/減速するオブジェクトに有効
  • Synchronize Values : スクリプト側で直接現フレームにおける速度と回転速度を与え、それを使って補間します。もっとも同期の精度が高いので、激しく動くオブジェクトに最適。アクションゲームにオススメします
  • Extrapolate Option : 補外処理。未来の座標を予測してオブジェクトを予め移動させておくことで同期による遅延を低減することができます。急激に速度が変化したりする動きが予測できないオブジェクトには使わない方が良いです

Synchronize Valuesを使用する時には以下のようにスクリプト側から値を渡してやる必要があります。

private PhotonTransformViewClassic photonTransformView;
private CharacterController characterController;
void Start()
{
    photonTransformView = GetComponent<PhotonTransformView>();
    characterController = GetComponent<CharacterController>();
}

private void Update()
{
    if (photonView.isMine)
    {
        //現在の移動速度
        var velocity = characterController.velocity;
        //移動速度を指定
        photonTransformView.SetSynchronizedValues(speed: velocity, turnSpeed: 0);
    }
}

Synchronize Rotation

  • Disable : 補間しない
  • Rotate Toward : 指定速度で補間する
  • Lerp : 線形補間

PhotonAnimatorView

Synchronize Paramergers

  • Disable : 同期しない
  • Discrete : 1秒間に10回のペースで同期を行う
  • Continuous : 1秒間に10回のペースでの同期は同じ。ただしこちらは毎フレームのパラメータ値を保存し、同期のタイミングでまとめて送信する。受信側では送られてきたパラメータ値を1フレームに1つずつ読み込んで再現する

IntegerやFloatなどの、値が細かく変動するものはContinuousで、大雑把で良いboolはDiscreteという感じで設定すると良いです。ただしContinuousは通信量が増えるデメリットがあります。

値が更新されたとみなす閾値を調整する

PhotonViewの監視対象の値が更新されたとみなす閾値は、PhotonNetworkから調整できます。

PhotonNetwork.PrecisionForVectorSynchronization = 0.00001f;
PhotonNetwork.PrecisionForQuaternionSynchronization = 1f;
PhotonNetwork.PrecisionForFloatSynchronization = 0.01f;

しかし、これはデータ型の単位でしか設定することができないので、使いづらいです。独自で実装してすると以下の様になります。

private Vector3 lastPosition = transform.position;

void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
    if (stream.IsWriting) {
        // 前回に送信した座標から、一定の距離以上移動した場合のみ現在の座標を送信する
        if (Vector3.Distance(transform.position, lastPosition) > 0.01f) {
            stream.SendNext(transform.position);
            lastPosition = transform.position;
        }
    } else {
        transform.position = (Vector3)stream.ReceiveNext();
    }
}
+2