Photonの実装③の動画の最後で、
Bキーを押して自分と相手のクライアントのプレイヤーの色を青色にしようとしているとこで終わっていますが、
自クライアントのプレイヤーが青色になったことが他クライアントに反映されるというだけの結果に終わってしまいます。
どうすれば両方のクラアントのプレイヤーの色を変えられるのかが知りたいです。
PlayerController.csの31~57行目の内容を添付画像のように変更すれば、
両プレイヤーの色を青く変更することが出来ますので、参考になさっていただければと思います。
自身だけのトリガーで全ユーザーののRpcChangeColorを呼び出すことはできますか?
「自身だけのトリガー」が photonView.isMine = true
を指しているのであれば、PhotonTargets.All
で自分を含めた全ユーザーに、PhotonTargets.Others
で自分以外のユーザー全員に、のように対象を変更できます。
https://doc-api.photonengine.com/en/pun/v1/group__public_api.html#gab84b274b6aa3b3a3d7810361da16170f
PhotonTargets.All
とすることでシーン上のすべてのオブジェクトのRPC関数を呼び出せると勘違いしていましたPhotonTargets
はどのクライアントでRPC関数を呼び出すか指定するパラメータなのですね
このスレッドの質問と同じところで詰まったので解答の通りにしたのですが、
これだとオブジェクトそれぞれでBキーが押されたと認識され、
双方が自身でRpcChangeColorを呼び出していることになりませんか?
[PunRPC]属性を付与していない関数でも同じ結果になりました
自身だけのトリガーで全ユーザーののRpcChangeColorを呼び出すことはできますか?
PhotonTargets.All
とすることでシーン上のすべてのオブジェクトのRPC関数を呼び出せると勘違いしていました。
PhotonTargets
はどのクライアントでRPC関数を呼び出すか指定するパラメータなのですね。
お騒がせしてすみませんでした。
また、コンソールを見ても、エラーを吐いていないので、何を修正したらいいのか分からず、困っています。
・上記「Bキー→青」の実装前の、「Pキーを押すと、赤色になる」については、問題なく実装できています。
・RPC通信周りの処理で「Debug.Log」を入れて、「Bキー」を押下後、下記のメソッドが呼ばれているか?処理は走っているのか、を確認
Bキーを押す↓
┗ RpcChangeColorメソッド
Debug.Log("RpcChangeColor was called. isRpcDone is now true.");は表示される。
┗ Updateメソッド
Debug.Log("Color should be blue.");は表示される。
ただ、上記状態であるにもかかわらず、「Bキー」を押しても、「青色」になりません。
if (isRpcDone) { Debug.Log("Color should be blue."); GetComponent().material.color = Color.blue; }
private void RpcChangeColor() { // 色変更処理 GetComponent().material.color = Color.blue; }
恐れ入りますが、ご教示の程、よろしくお願いいたします。
※プレファブ(Sphere)のInspector設定キャプチャを添付します。
※Photonは、「Photon Unity Networking Classic - FREE」を使用しています。
versionは、1.105 となります。
自分なりに調べたり、リトライしながら、レクチャー動画内の以下仕様を実装できましたので、ご報告いたします。
【仕様】
・操作できるオブジェクト(※所有権を持ったオブジェクト?)
┗ Pキーを押すと、赤色になる。
・操作していないオブジェクト(※所有権を持っていないオブジェクト?)
┗ Pキーを押しても、赤色にはならず、デフォルトの黒のまま。
・Bキーを押すと、生成された全てのオブジェクトが青色になる。
※上記の仕様は、どちらの画面にも反映される。
※UnityエディタのGame画面上や、実行されたexeファイルの再生画面上をクリックすると、操作できるオブジェクト(所有権?)が変わりました。
【追加仕様】
・Bキーを押して、生成された全てのオブジェクトが青色になる
┗ さらにBキーを押すと、青色になる前の色に戻る。以上の実装が完了いたしました。
※修正した「PlayerController.cs」を添付させていただきます
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] private PhotonView _photonView;
private bool isColor = default;
private bool isRpcDone = default;
private void Update()
{
if (_photonView.isMine)
{
if (Input.GetKey(KeyCode.UpArrow))
{
transform.Translate(new Vector3(0, 0, 0.1f));
}
else if (Input.GetKey(KeyCode.DownArrow))
{
transform.Translate(new Vector3(0, 0, -0.1f));
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(new Vector3(-0.1f, 0, 0));
}
else if (Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(new Vector3(0.1f, 0, 0));
}
}
if (Input.GetKeyDown(KeyCode.P) && _photonView.isMine)
{
isColor = !isColor;
}
if (Input.GetKeyDown(KeyCode.B))
{
_photonView.RPC("RpcToggleBlueColor", PhotonTargets.All);
}
if (isRpcDone)
{
Debug.Log("Color should be blue.");
GetComponent().material.color = Color.blue;
}
else if(isColor)
{
GetComponent().material.color = Color.red;
}
else
{
GetComponent().material.color = Color.black;
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
stream.SendNext(isColor);
stream.SendNext(isRpcDone);
}
else
{
isColor = (bool)stream.ReceiveNext();
isRpcDone = (bool)stream.ReceiveNext();
}
}
[PunRPC]
private void RpcToggleBlueColor()
{
isRpcDone = !isRpcDone;
Debug.Log("RpcToggleBlueColor was called. isRpcDone is now true.");
}
}
相手のPhotonのオブジェクトに変更を加えても、所有権が相手側にあると自分の画面では変更が反映されていても相手の画面では変更がされません。
そのため、相手に変化を加える際は一時的に相手のオブジェクトの所有権を自分のものにする必要があります。
所有権の変更は
該当のオブジェクト.PhotonView.TransferOwnership(所有権を譲渡するプレイヤーのID);一時的に所有権を自分のものにし、相手に返す場合は
該当のオブジェクト.GetComponent<PhotonView>().TransferOwnership(PhotonNetwork.player.ID);
//PhotonNetwork.player.IDは自分のIDを取得できる
オブジェクトを青色にするスクリプト;
該当のオブジェクト.GetComponent<PhotonView>().TransferOwnership(相手のID);
上記のような流れにすることで相手の画面でも変更を反映させることができます。